Kevin Zaki
Kevin Zaki

Reputation: 146

C system calls — keep getting error with lseek and read

This is a practice exercise I am working on for class and I don't understand why this won't run...

I get the problem when trying to assign a char array (buffer) with a length from a variable (num2).

You can execute the file like so:

./file.c offset numOfChars filename.txt

./file.c 4 10 somefile.txt

If somefile contained the text:

Why isn't this c program working. I can't figure it out

The program should print

isn't this

Here is the code:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>

main(int ac, char *av[]){
    // Save the command line variables
    int num1 = av[1];
    int num2 = av[2];

    long numbyte1 = av[1];
    long numbyte2 = av[2];

    int fd = open(av[3], O_RDONLY);

    // Try to open the file
    if( fd < 0 )
        perror(fd + " - Could not open file!");

    // use stat to get file size
    struct stat sb;
    if(fstat(fd,&sb) < 0)    
        return 1;

    // Check to see if the file is big enough for the provided offset
    if(sb.st_size < num1+num2){
        perror(fd + " - Size of file is not large enough for provided offset!" + fd);
    }

    char buffer[num2];

    if(lseek(fd, numbyte1 ,SEEK_SET) < 0) return 1;

    if(read(fd, buffer, numbyte2) != numbyte2) return 1;

    printf("%s\n", buffer);

    return 0;
}

Upvotes: 1

Views: 1043

Answers (1)

R Sahu
R Sahu

Reputation: 206567

Issues that I see:

  1. ./file.c is not the proper way to run the program. You need to compile the program and create an executable. Then, you can run it.

    If you have gcc, use:

    gcc -o file -Wall file.c
    ./file 4 10 somefile.txt
    
  2. These lines

    int num1 = av[1];
    int num2 = av[2];
    

    are not right. The compiler should report warnings. Using gcc, I get the following warnings for those two lines:

    soc.c: In function ‘main’:
    soc.c:4:15: warning: initialization makes integer from pointer without a cast [enabled by default]
    int num1 = av[1];
               ^
    soc.c:5:15: warning: initialization makes integer from pointer without a cast [enabled by default]
    int num2 = av[2];
    

    av[1] and av[2] are of type char*. If the contain integers, you can extract the integers from them by using one of several functions from the standard library. E.g.

    int num1 = atoi(av[1]);
    int num2 = atoi(av[2]);
    
  3. The lines

    long numbyte1 = av[1];
    long numbyte2 = av[2];
    

    suffer from the same problem. You can use the already extracted numbers to intiaize numbypte1 and numbypte2

    long numbyte1 = num1;
    long numbyte2 = num2;
    
  4. You have

    char buffer[num2];
    

    that will be not enough to hold a string that has num2 characters. You need another element in the array to hold the terminating null character. Use:

    char buffer[num2+1];
    
  5. Add a terminating null character to buffer after you read the data from the file.

    if(read(fd, buffer, numbyte2) != numbyte2) return 1;
    buffer[num2] = '\0';
    

Upvotes: 1

Related Questions