Reading a file in C: different behavior for "r" and "a +" flags

I want to open a file, read its contents, and then add a line to the file. I thought I should use the "+" flag for the task.

I have a function that opens a file and returns a pointer to that file.

FILE* open_weekly_disk_file(char* filename){
    FILE* weekly_log;

    weekly_log = fopen(filename, "a+");
    //weekly_log = fopen(filename, "r");

    if(! weekly_log){
        printf("The attempt to open the weekly log failed!\n");
        return NULL;
    } else{
        return weekly_log;
    }
}

      

Then I have a function that calls the above function and uses scanf to read the content from the file:

void sample_function(char* filename){
    FILE* log;
    char token[100], current_read[100];
    int limit;

    log = opened_weekly_disk_file(filename);
    // The problem happens here
    for(limit=0; limit < TOKEN_NUMBER; limit++){
        if(fscanf(log, "%s%s", &token, &current_read) == 2){
            printf("%s %s\n", token, current_read);
        }
    }
    ...
}

      

This code works when I use:

weekly_log = fopen(filename, "r");

      

But doesn't work when I change the "r" flag to "a +". I am getting a segmentation fault right before the for loop.

0


source to share


2 answers


This is because spec mode "a"

opens a file for appending, with a file pointer at the end. If you try to read here, there is no data as the file pointer is at EOF. You must open with "r+"

read and write. If you read the entire file before writing, then the file pointer will be correctly positioned to add additional data when writing.



If that's not enough, review the functions ftell()

and fseek()

.

+5


source


from this SO Q

from the man page: a +

Open for reading and adding (write at the end of the file). File if it doesn't exist. The starting position of the file to be read is at the beginning of the file, but output is always appended to the end of the file.

Answer:

There is only one pointer, which is initially at the beginning of the file, but when a write attempt is made, it moves to the end of the file. You can move it with fseek or rewind anywhere in the file for reading, but write operations will return it to the end of the file.



So, the problem is not that the file is being opened in append mode, because that is not the case as far as reading is concerned.

The problem is what your code is doing at these three points

log = opened_weekly_disk_file(filename);
    ...

      

The code is most likely written to the file, causing the cursor to move to the end before reading begins.

+5


source







All Articles