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