Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading and appending to the same file

Tags:

c

file

I am new to C programming and just writing a simple program to read all the lines from a text file and replace each number with a new one. Here is my code. It prints to the console for each line but not to the file. Can someone please suggest what is wrong with my code?

#include <stdio.h>
int main(int argc, char *argv[])
{
    FILE * file_ptr;
    int num; 
    char line[128];
    file_ptr = fopen (argv[1], "a+");
    if(file_ptr==NULL)
    {
        printf("Error opening file");
    }

    if(file_ptr!=NULL)
    {
        while(fgets(line,128,file_ptr)!=NULL)   
        {
            fputs("df",file_ptr);   
            printf("2");
        }
    }

    fclose(file_ptr);
    return(0);
}
like image 903
user1042327 Avatar asked Jan 09 '23 05:01

user1042327


1 Answers

The problem is that you're reading and writing from the same file, and your reads and writes interact.

Opening the file with the mode a+ (append, allowing reading) sets the file position at the beginning of the file, so the first call to fgets reads the first line. But in append mode, all writes are performed at the end of the file. So the first call to fputs sets the file position to the end of the file, then writes df. Since there's a single file position for both reading and writing, the next call to fgets is performed at the end of the file, and reads nothing.

The behavior of file position makes the mode a+ appropriate mostly when you want to read the whole current content of a file and then add something at the end.

Note that the only way to modify the content in the middle of a file is to replace a sequence of bytes by a sequence of bytes with the same length. So you can replace 12 by df, but you can't replace 123 by df: if you set the file position where 123 is located and write df, you'll end up with df3. To replace numbers by strings of potentially different length, you'll need to rewrite the file as a whole

When you want to completely modify a file, there are three main techniques:

  • Load the current content in memory, truncate the file to 0, write the new content.
  • Open the current file for reading, create a new file, write the new content to the new file, close the old file, then move (rename) the new file to overwrite the old file.
  • Rename the old file, create a new file with the original name, read the current content from the renamed file, write the new content and close the files.

The first method has a major downside: if your program crashes or the computer loses power, the file will be lost. Thus you should almost always use one of the other two approaches: they use more disk space but the added safety is almost always worth it.

like image 114
Gilles 'SO- stop being evil' Avatar answered Jan 18 '23 10:01

Gilles 'SO- stop being evil'