user787084
user787084

Reputation:

feof wrong loop in c

I use below code to read a char from file and replace it with another, but I have an error.loop in going to end of file.

What is wrong?

I tested this code on linux (netbeans IDE) and it was correct and worked beautiful but when I tried to use VS 2008 in windows , I found a non end loop.

//address = test.txt

FILE *fp;
fp=fopen(address,"r+");
if(fp == 0)
{
    printf("can not find!!");
}
else
{
    char w = '0';  /// EDIT : int w;
    while(1)
    {
        if((w = fgetc(fp)) != EOF)
        {
            if((w = fgetc(fp)) != EOF)
            {
                fseek(fp,-2,SEEK_CUR);
                fprintf(fp,"0");
            }
        }
        else
        {
            break;
        }
    }
} 
fclose(fp);

Upvotes: 4

Views: 977

Answers (2)

cnicutar
cnicutar

Reputation: 182794

You are storing the result of fgetc in a char, instead of an int.

char w = '0'; /* Wrong, should be int. */

Incidentally, this problem is mentioned in the C FAQ.

If type char is unsigned, an actual EOF value will be truncated (by having its higher-order bits discarded, probably resulting in 255 or 0xff) and will not be recognized as EOF, resulting in effectively infinite input.

EDIT

Reading your question again, it's highly fishy the way you seek back two characters and write one character. That could well lead to an infinite loop.

EDIT2

You (likely) want something like this (untested):

while ((w = getc(fp)) != EOF) {
    fseek(fp, -1, SEEK_CUR);
    fprintf(fp, "0");
    fflush(fp); /* Apparently necessary, see the answer of David Grayson. */
}

Upvotes: 6

David Grayson
David Grayson

Reputation: 87541

The fopen documentation on cplusplus.com says:

For the modes where both read and writing (or appending) are allowed (those which include a "+" sign), the stream should be flushed (fflush) or repositioned (fseek, fsetpos, rewind) between either a reading operation followed by a writing operation or a writing operation followed by a reading operation.

We can add an fflush call after the fprintf to satisfy that requirement.

Here is my working code. It creates a file named example.txt and after the program exits that file's contents will be 000000000000n.

#include <stdio.h>

int main(int argc, char **argv)
{
    FILE * fp;
    int w;

    fp = fopen("example.txt","w");
    fprintf(fp, "David Grayson");
    fclose(fp);

    fp = fopen("example.txt","r+");
    while(1)
    {
        if((w = fgetc(fp)) != EOF)
        {
            if((w = fgetc(fp)) != EOF)
            {
                fseek(fp,-2,SEEK_CUR);
                fprintf(fp,"0");
                fflush(fp);  // Necessary!
            }
        }
        else
        {
            break;
        }
    }
    fclose(fp);
}

This was tested with MinGW in Windows.

Upvotes: 3

Related Questions