Search code examples
cfile-handling

Add a line of text after the nth line in a txt file using c file handling


I want to add a line of text after the fifth line in a text file.This is my code:

#include <stdio.h> 

int main(){
  FILE *f;
  f = fopen("file1.txt", "r");

  int nCount = 0;
  char c = fgetc(f);
  while(nCount != 5){
    if(c == '\n'){
      nCount++;
    }
    // c = fgetc(f);
    fseek(f, 1, SEEK_SET);
  }

  c = fgetc(f);

  fprintf(f, "I have appended a line");
  
 
  return 0;
}

Line is not being appended.What is wrong?


Solution

  • If your text file is of a reasonable size (to fit into memory) the following works with one open file... I leave it as an exercise to deal with the Windows/DOS convention of CRLF where LF works just as well. (This is just a rough cut, but it may lead you to the results you want.)

    It could do with more testing of return values, especially the fwrite() calls.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int my_main() {
        char *fname = "log.txt";
    
        FILE *fp = fopen( fname, "rb+" );
        if( fp == NULL ) {
            fprintf( stderr, "Cannot open %s r/w\n", fname );
            return 1;
        }
    
        // measure space needed
        fseek( fp, 0, SEEK_END );
        size_t size = ftell( fp );
        fseek( fp, 0, SEEK_SET );
    
        // get space
        char *iobuf = (char*)malloc( size );
        if( iobuf == NULL ) {
            fprintf( stderr, "Cannot allocate %ld byte buffer\n", size );
            fclose( fp );
            return 1;
        }
    
        // load entire file
        size_t nread = fread( iobuf, sizeof(char), size, fp );
        if( nread != size ) {
            fprintf( stderr, "Expecting %ld - Read %ld\n", size, nread );
            return 1;
        }
    
        int lnCnt = 5; // skip past 5 lines
        for( char *cp = iobuf; cp < iobuf + size; cp++ )
            if( *cp == '\n' && --lnCnt == 0 )
                break;
        cp += 1;
        // Up to you to handle situation where #lines < 5
    
        // position after 5th '\n'
        fseek( fp, cp - iobuf, SEEK_SET );
    
        // write the new string
        char *newText = "I wish I was a fish\n"; // Written after whatever line
        fwrite( newText, sizeof newText[0], strlen( newText ), fp );
    
        // then write back the rest
        fwrite( cp, sizeof *cp, size - (cp - iobuf), fp );
    
        fclose( fp );
    
        return 0;
    }
    

    Output:

    This is line 1
    This is line 2
    This is line 3
    This is line 4
    This is line 5
    I wish I was a fish
    This is line 6
    This is line 7