Gowtham Gampala Ответов: 2

Сомнение файлами в с++...


#include<stdio.h>
int main()
{
    FILE *fptr;char ch;
    char fname[15];
    puts("Enter file name with directory");
    gets(fname);
    fptr=fopen(fname,"r+");
    if(fptr==NULL)
    {
        puts("Not successful");
    }
    else{
            puts("Successfully opened");getch();
    while(1)
    {
        ch=fgetc(fptr);
        if(ch==EOF)
        {
            break;
        }
        if(ch==';')
        {
           fseek(fptr,-1,SEEK_CUR);
           fputc('$',fptr);
           fseek(fptr,0,SEEK_CUR);---------->//////[HERE]//////
        }
    }


    }
    puts("Replacement Completed successfully");
    fclose(fptr);
    return 0;
}

Это я проаграмма в c, чтобы заменить символ в файле другим.... если я удалю строку [здесь], эта проаграмма никогда не остановится.Но это не делает Ану sence..as fseek(fptr, 0, SEEK_CUR); ничего не делает..пожалуйста, помогите мне

Что я уже пробовал:

я триен в codeblocks и devcpp

Graeme_Grant

И в чем твоя проблема????

Пожалуйста, нажмите на кнопку "улучшить вопрос" и обновите его с дополнительной информацией. Если вы не знаете, как это сделать, пожалуйста, прочтите это: Проект Кодекса быстрых ответов часто задаваемые вопросы - Как получить вопрос[^]

Richard MacCutchan

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

Jochen Arndt

Описание проблемы находилось в конце блока кода.
Я отредактировал вопрос, чтобы показать его теперь как обычный текст.

Graeme_Grant

Я был уверен, что раньше такой проблемы не было... Должно быть, я его пропустил. Извиняюсь.

2 Ответов

Рейтинг:
6

Jochen Arndt

Видеть ссылка на fseek - C++ [^]:

Цитата:
В потоках, открытых для обновления (чтение+запись), вызов fseek позволяет переключаться между чтением и записью.
Это означает, что всякий раз, когда вы меняете направление ввода-вывода потока, вы должны позвонить fseek Причина в том, что есть две внутренние позиции файла: одна для чтения и одна для записи, но только соответствующая обновляется с помощью чтения или записи. fseek обновит оба до позиции последней операции.

В вашем случае fputc('$') обновит позицию записи, но не позицию чтения, которая все еще будет находиться на позиции символа';'. Таким образом, этот символ будет прочитан снова со следующей итерацией цикла, что приведет к бесконечному циклу. Но ... fseek вызов устанавливает позицию чтения в текущую позицию записи, которая находится на один шаг позади.

КСТАТИ:
Как вы думаете, достаточно ли буфера из 15 символов для хранения полного пути (каталога с именем файла)?
Воспользуйся PATH_MAX вместо этого который определяется в лимитов.ч.


Gowtham Gampala

Спасибо вам сэр :)

Gowtham Gampala

Iam использует каталог по умолчанию...где присутствует программа

Jochen Arndt

Вы печатаете "введите имя файла с каталогом".

15 было бы достаточно для DOS (8.3 имен файлов), но не для Windows или Linux, где имена файлов могут быть длиннее.

Благодарю вас также за то, что вы приняли мое решение.

Gowtham Gampala

да, но ... все равно я использую каталог по умолчанию

Jochen Arndt

Но даже каталог по умолчанию может содержать файлы с более длинными именами, такими как
"This_is_a_quite_long_file_name. ascii"

Рейтинг:
19

OriginalGriff

В этом есть смысл.
fseek устанавливает положение файла в выбранном месте.
А если вы прочтете документацию: ссылка на fseek - C++ [^] это очень ясно:

Цитата:
Внутренний индикатор конца файла потока очищается после успешного вызова этой функции, и все эффекты от предыдущих вызовов ungetc в этом потоке отбрасываются.

Итак, с этой строкой следующий звонок fgetc не возвратит EOF.


Gowtham Gampala

Может у пожалуйста, elobarate???Теперь я перехожу к программированию..

OriginalGriff

Читать документацию. Я не могу вдаваться в подробности!