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

Time:08-17

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?

CodePudding user response:

What is wrong?

You can't insert data in the middle of a file without shifting all the later lines.


To add a line, consider forming a new file.

// Pseudo code
Open input file
Open output file
nth_line_found = false
while ((len = read_a_chunk(input, buffer)) > 0) 
  if (!nth_line_found) {
    Count lines in buffer
    while counting, 
      if (count == nth) {
        write first part of buffer
        write "I have appended a line\n"
        write last part of buffer
        nth_line_found = true
    if (nth_line_found still false) write buffer
  } else {
    write buffer
  }

  If desired, delete input file and rename output to input.

This approach implies reading with fread() rather than fgets() to avoid length (and null character) limitations of fgets().

CodePudding user response:

THIS IS JUST A SKETCH!

Read the shole file into memory

fopen();
int lineno = 0;
while (fgets()) {
    addlinetomemory();
    lineno  ;
    if (lineno == 42) addextraline();
}
fclose();

now reopen in write mode

fopen();
for (int line = 0; line < lineno; line  ) {
    fputs(); // write line
}
fclose();

Voila!

CodePudding user response:

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

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

f_in=fopen("file1.txt", "rt");
if(!f_in) return -1;
f_out=fopen("file2.txt", "wt");
if(!f_out) return -1;

char *oneLine = (char*) malloc(LINE_MAX);
if(oneLine){

    int lineCounter=0;

    while(fgets(oneLine,LINE_MAX,f_in)){
        lineCounter  ;
        fputs(oneLine,f_out);
        if(lineCounter == 5)
            fputs("a new line\n",f_out);
    }

    fclose(f_in);
    fclose(f_out);
    free(oneLine);
    unlink("file1.txt");
    rename("file2.txt","file1.txt");
    return 0;
} else
    return -1;
}

CodePudding user response:

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
  • Related