Search code examples
coffsetfseek

SEEK_SET doesn't set the pointer to the start of the file


I'm trying to save this .txt file in the array as columns.

19 17 20 18
9  6  10 9 
12 11 10 16
3  7  9  10
0  5  8  6 
15 13 15 15
20 18 18 16
17 19 19 18
13 15 14 12
10 13 18 15

This is what I have done so far,

    FILE *fp;
    int temp;
    int arr[4][10];

    fp = fopen("grade.txt", "r");

    for (int i = 0; i < 4; i++) {
        fseek(fp, i * 3, SEEK_SET);

        int c;
        for (int j = 0; j < 10; j++) {
            fseek(fp, i * 3, SEEK_CUR);
            fscanf(fp, "%d", &temp);
            arr[i][j] = temp;

            while ((c = fgetc(fp)) != '\n') {
                if (c == EOF)
                    break;
            }
        }
    }

and this is the array I actually created,

arr[0] = 19 9 12 3 0 15 20 17 13 10 
arr[1] = 20 6 11 7 5 13 18 19 15 13 
arr[2] = 9 10 9 8 15 18 19 14 18 18 
arr[3] = 10 16 10 6 15 16 18 12 15 15 

As you see, the first column was successfully saved, but starting the second one, it gets weird. It seems, fseek(fp, i * 3, SEEK_SET) doesn't set the pointer to the start of the file, because if it did, arr[1][0] should be 17, not 20. Can anyone explain what is actually going on here?


Solution

  • In the inner loop, you want to go to the proper "vertical" place in the file. I see this code, which, I guess, intends to do that:

    fseek(fp, i * 3, SEEK_CUR);
    

    It's wrong for more than one reason. To save time/money, just note that you cannot fix it: you don't know how many bytes one line in your file occupies.

    To fix it, read your file in natural order, and delete both calls to fseek. Because RAM is more flexible in access order than files, this is the most sensible thing to do. You can read the file in natural order, and store the data in transposed order.