неправильная петля в с - PullRequest
4 голосов
/ 09 июля 2011

Я использую приведенный ниже код, чтобы прочитать символ из файла и заменить его другим, но у меня есть error.loop при переходе в конец файла.

Что не так?

Iпротестировал этот код на linux (IDE NetBeans), и он был корректным и работал прекрасно, но когда я попытался использовать VS 2008 в Windows, я обнаружил неконечный цикл.

//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);

Ответы [ 2 ]

6 голосов
/ 09 июля 2011

Вы сохраняете результат fgetc в символе вместо целого.

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

Кстати, эта проблема упоминается в C FAQ .

Если тип char равен unsigned, фактическое значение EOF будет усечено (при отбрасывании его битов более высокого порядка, что, вероятно, приведет к 255 или 0xff) и не будетраспознается как EOF, , что приводит к фактически бесконечному вводу .

РЕДАКТИРОВАТЬ

Повторное чтение вашего вопроса, это очень подозрительно, как вы ищетевернуться два символа и написать один символ.Это может привести к бесконечному циклу.

EDIT2

Вы (вероятно) хотите что-то вроде этого (не проверено):

while ((w = getc(fp)) != EOF) {
    fseek(fp, -1, SEEK_CUR);
    fprintf(fp, "0");
    fflush(fp); /* Apparently necessary, see the answer of David Grayson. */
}
3 голосов
/ 09 июля 2011

Документация fopen на cplusplus.com гласит:

Для режимов, в которых как чтение, так и написание (или добавление) разрешено (те, которые включают знак «+»), поток должен быть сброшен (fflush) или переставлен (fseek, fsetpos, перемотка) между операцией чтения с последующей операцией записи или операция записи с последующим операция чтения.

Мы можем добавить fflush вызов после fprintf, чтобы удовлетворить это требование.

Вот мой рабочий код. Он создает файл с именем example.txt, и после выхода из программы его содержимое будет 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);
}

Это было протестировано с MinGW в Windows.

...