Search code examples
cstringfilefreadfseek

Reading line by line using fread and fseek


im trying to read a .txt file, line by line, where each line is 19 characters long, this is my code (I want to only use fseek and fread to understand pointers rightly):

int main(int argc, char *argv[]){
    FILE *file = fopen(argv[1], "r");
    if(file == NULL){
        perror("fopen");
        return 0;
    }
    int i = 0;
    int j = 0;
    char L[20];
    while(1){
        if(feof(file)){
            break;
        }
        fseek(file, i*20, SEEK_SET);
        fread(L,19,sizeof(char),file);
        printf("%s\n", L);
        i++;
        }
    fclose(file);
    return 0;   
 }

What I think should happen with this is that I move the pointer to the file to the start of each line in a loop, then move one line and so. The source .txt file is:

123456789:123456789
perro:guau         
gato:miau          
                   
vaca:muuu          
                   
lobo:auuu          
                   

while the output I get from my program is:

123456789:123456789�V
perro:guau         �V
gato:miau          �V
                   �V
vaca:muuu          �V
                   �V
lobo:auuu          �V
                   �V
                   �V

I tried changing the 20s and 19s since I dont know if im including the end of string character in the right way, but got even worse results, any help would be apreciated.


Solution

    • OP's code has undefined behavior, (UB) as "%s" expects a string. Yet L[] lacks a null character. To print a character array, use "%.*s"

    • Check fread() return value, not feof().

    • Use return value of fread() to know how much was read.

    • Review argument order for fread(void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream);

    Sample:

    size_t sz = sizeof L / sizeof L[0];
    size_t n;
    while((n = fread(L,sizeof L[0], sz, file)) > 0) {
      printf("<%.*s>\n", (int) n, L);
      i++;
      fseek(file, i*20, SEEK_SET);
    }
    

    fread() is not the best tool to read a line. Research fgets() instead.

    "each line is 19 characters long," --> C defines a line as "each line consisting of zero or more characters plus a terminating new-line character." From a C-point-of-view, your lines include a new-line and so are 20 characters total.