I want to open a file, read its contents, and then append a line to the file. I thought I should use the "a+" flag for the task.
I have a function which opens a file and returns a pointer to this 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 which calls the function above and uses scanf to read contents 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, ¤t_read) == 2){
printf("%s %s\n", token, current_read);
}
}
...
}
This code works when I use:
weekly_log = fopen(filename, "r");
But does not work when I change the "r" flag to "a+". I get a Segmentation fault right before the for loop.
That is because the mode spec "a"
opens a file for appending, with the file pointer at the end. If you try to read from here, there is no data since the file pointer is at EOF. You should open with "r+"
for reading and writing. If you read the whole file before writing, then the file pointer will be correctly positioned to append when you write more data.
If this is not enough, please explore ftell()
and fseek()
functions.
from this SO QA
from the man page:
a+
Open for reading and appending (writing at end of file). The file is
created if it does not exist. The initial file position for reading is
at the beginning of the file, but output is always appended to the end
of the file.
Answer:
There is just one pointer which initially is at the start of the file
but when a write operation is attempted it is moved to the end of the
file. You can reposition it using fseek or rewind anywhere in the file
for reading, but writing operations will move it back to the end of
file.
So, the problem is not the fact that the file is opened in append mode, because it is not, as far as reading from it is concerned.
The problem lies in what your code does in those three dots
log = opened_weekly_disk_file(filename);
...
The code quite probably writes to the file, making the file cursor move to the end of it before the reading occurs.