0

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, &current_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.

RebeccaK375
  • 871
  • 3
  • 17
  • 28
  • Don't use YODA conditions, and instead make your code more readable by using more whitespace, YODA conditions are not the natural way to think of it and it makes reading it unpleasant. And try not to mix declarations with statements. And finally what is the actual problem? it's not clear in your question what doesn't work and why do you think it behaves differently than what you expect. – Iharob Al Asimi Jul 23 '15 at 22:18

2 Answers2

6

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.

Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • Good guess, it can't be anything else. Although the OP didn't mention what was the problem, this has to be it. – Iharob Al Asimi Jul 23 '15 at 22:21
  • 2
    please read [this](http://stackoverflow.com/questions/3645123/opening-a-file-in-a-mode) – Pynchia Jul 23 '15 at 22:27
  • please see my answer and let me know what you think – Pynchia Jul 23 '15 at 22:37
  • Changing to the r+ worked, but originally, I did not use the "a" flag. From reading the answer by Pynchia, the flag should keep the pointer at front until the very first read command. – RebeccaK375 Jul 24 '15 at 15:43
5

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.

Community
  • 1
  • 1
Pynchia
  • 10,996
  • 5
  • 34
  • 43
  • Yeah. I agree with you. I was surprised when I read the accepted answer. I think that problem is not originated from use of `a+` – Soner from The Ottoman Empire Jul 23 '15 at 22:39
  • @itsnotmyrealname I was surprised too, since in hindsight my answer concerned `"a"` and not the `"a+"` in the question. Up voted. – Weather Vane Jul 23 '15 at 22:50
  • You have written `does not work when I change the "r" flag to "a+"`. So you can edit your question – Soner from The Ottoman Empire Jul 23 '15 at 22:56
  • When i changed the a+ to r+ tag, I was no longer getting the segmentation fault, so I chose the above answer. Those "..." have nothing but definitions of some other variables that I hope to use. I do not use any functions other than fscanf for the file. – RebeccaK375 Jul 24 '15 at 15:36