简体   繁体   中英

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;
}

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:

    \nsoc.c: In function 'main': \nsoc.c:4:15: warning: initialization makes integer from pointer without a cast [enabled by default] \nint num1 = av[1]; \n           ^ \nsoc.c:5:15: warning: initialization makes integer from pointer without a cast [enabled by default] \nint num2 = av[2]; \n

    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. Eg

     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'; 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM