Reading and appending to one file

I am new to C programming and am just writing a simple program to read all lines from a text file and replace each number with a new one. Here is my code. It prints to the console for every line, but not for 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);
}

      

+3


source to share


2 answers


The problem is that you are reading and writing from the same file and your reads and writes are interacting.

Opening a file in a+

(append, read) mode sets the file position at the beginning of the file, so the first call fgets

reads the first line. But in add mode, all writes are done at the end of the file. Thus, the first call fputs

sets the file position to the end of the file and then writes df

. Since there is one file position to read and write, the next call fgets

is made at the end of the file and reads nothing.

The file position behavior makes the mode a+

more convenient when you want to read all of the current file content and then add something at the end.

Note that the only way to change the content in the middle of the file is to replace the sequence of bytes with a sequence of bytes of the same length. So you can replace 12

with df

, but you cannot replace 123

with df

: if you set the file position where it is 123

and write df

, you get df3

. To replace the numbers with lines of potentially different lengths, you need to rewrite the file as a whole



If you want to completely change a file, there are three main methods:

  • Load the current content into memory, trim the file to 0, write new content.
  • Open the current file for reading, create a new file, write new content to a new file, close the old file, and 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 significant drawback: if your program crashes or the computer loses power, the file will be lost. As such, you should almost always use one of the other two approaches: they use more disk space, but the added security is almost always worth it.

+8


source


The following code, which incorporated several oversights in the OP code
will tell the user about any error conditions that occur

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    FILE * file_ptr;

    char line[128];

    if( 2 > argc )
    { // then invalid number of parameters
        printf( "\nUsage: %s filename\n", argv[0]);
        exit(EXIT_FAILURE );
    } // end if

    // implied else, file name parameter exists

    if( NULL == (file_ptr = fopen (argv[1], "a+") ) ) // open for read and append
    { // then fopen failed
        perror( "fopen failed" ); // output reason for failure to open file
        exit(EXIT_FAILURE );
    } // end if

    // implied else, fopen successful

    // note: second pass through this loop will fail as file pointer will be at end of file
    // always put literal first, so compiler will catch syntax errors
    while(NULL != fgets(line,sizeof(line),file_ptr) )
    {
        if( EOF == fputs("df",file_ptr) )// appends 'df' to end of file
        { // then fputs failed
            perror( "fputs failed" );
            exit( EXIT_FAILURE );
        }

        // implied else, fputs successful

        printf("2");
        fflush( stdout );
    } // end while

    fclose(file_ptr);
    return(0);
} // end function: main

      



0


source







All Articles