简体   繁体   中英

Trying to write at end of each line in a File in C Language?

I have been trying from past 3 hours and stuck at one point. I want to add some content after each line in a File using C.

Here's My Code

int main(){

FILE *fp;
char c;
int p;

fp = fopen("example1.txt","r+");

if (fp == 0) {
    perror("No File");
    exit(-1);
}

while ( (c = fgetc(fp)) != EOF) {
    if (c != '\n')
        printf("%c",c);
    else {
        //Going back two points is for '\n'
        fseek(fp,-2,SEEK_CUR);
        fprintf(fp,"=2\n");
    }
}


fclose(fp);
return 0;
}

The Input File:

1+1
1+1
1+1

The Desired Output:

1+1=2
1+1=2
1+1=2

The Real Output:

1+1=2
=2
=2
=2
=2
=2

The Execution gets into Infinite Loop..

Let's say you have one line of text in the file.

1+1

If you look at the contents byte wise as characters, you'll see:

+---+---+---+----+
| 1 | + | 1 | \n |
+---+---+---+----+

When you encounter the '\\n' , you go back two characters and print "=2\\n" to the file. After, the contents of the file will be:

+---+---+---+----+
| 1 | = | 2 | \n |
+---+---+---+----+

The call to fprintf does not change the position from where you read the data. Hence, the read position is at the second character, '=' , of the file.

The entire process repeats. The contents of the file remain

+---+---+---+----+
| 1 | = | 2 | \n |
+---+---+---+----+

The output continues to be

=2

after the first line.

Reading from and writing to the same file is fraught with too many pitfalls. It will be better if you separate them.

I had faced the same problem. I got it to work partially.At the desired position, I used ftell to get the current position. I subtracted this from the initial file size and stored in remainingSize variable. Using fread I got the chars after this position into a buffer. Then I wrote the desired output at current position.Then I wrote the data from buffer back into the file. This worked for small data, but there was a bug in my code which I couldn't resolve and it led to ftell returning an out of range value.

It could be explained as

if the data is

+---+---+---+----+
| 1 | + | 1 | \n |
+---+---+---+----+
+---+---+---+----+
| 3 | * | 5 | \n |
+---+---+---+----+

let's say size of file is 'x' You go to the point after 1. By ftell, u can get the current pos 'y' You have to read 'x'-'y' chars and bring them into buffer You can write the desired output at current position and then write the contents of buffer back to the file

+---+---+---+----+
| 1 | + | 1 | = | 2
+---+---+---+----+

Buf =
+---+---+---+----+
| \n | 3 | * | 5 |\n
+---+---+---+----+

I think this solution is inefficient as it involves many reads and writes and may not work on big files.

You have to rewrite the entire file, other than the first line. Trying to do that in-place to the existing file is actually pretty difficult given arbitrarily long lines in an arbitrarily-large file.

So it's much, much easier to just write a new file.

Something like this (completely lacks any error checking):

// open files
FILE *in = fopen( "infile.txt", "r" );
FILE *out = fopen( "infile.txt.tmp", "w+" );
// getline() variables
char *line = NULL;
size_t len = 0UL;
ssize_t result;

// buffer for output line
// (hope it's long enough...)
char buffer[ 1024 ];
for ( ;; )
{
    // getline() makes this so much easier...
    result = getline( &line, &len, in );
    if ( result == -1 )
    {
        break;
    }
    // strip newline
    char *p = strchr( line, '\n' );
    if ( p != NULL )
    {
        *p = '\0';
    }
    // append "=2" to each line
    snprintf( buffer, sizeof( buffer), "%s%s\n", line, "=2" );
    fputs( buffer, out );
}
fclose( in );
fclose( out );
// assume POSIX rename is available
rename( "infile.txt.tmp", "infile.txt" );

Read the file line-by-line, append the new data to the end of each line, write the new line to a new file , then when done rename() the new file to the old file name.

Normally, I'd add whitespace between lines to aid in readability, but the extra lines cause a scrollbar to appear on the code, making it less readable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM