2016-07-25 5 views
-2

Я изучаю файл ввода/вывода. Код в блоке связывает некоторые функции, такие как: fgetc(), fgets(), fputs(). я не знаю, почему это не работает точно так, как я хочу. Большое вам спасибо! Ниже мой код:Почему ввод «abc !!!» но выход не «abC+++»?

#include <stdio.h> 
int main() 
{ 
    FILE *fp; //FILE type pointer 
    int c; //using to get each character from file 
    char buffer [256]; //array as buffer to archive string 

    fp = fopen("file.txt", "r"); /*open a file with only read mode*/ 
    if(fp == NULL) 
    { 
     perror("Error in opening file"); 
     return(-1); 
    } 
    while(!feof(fp)) /*check if has not yet reached to end of file*/ 
    { 
     c = getc (fp); //get a character from fp   
     if(c == '!') 
     { 
     ungetc ('+', fp); //replace '!' by '+' 

     } 
     else 
     { 
     ungetc(c, fp); //no change 
     } 
     fgets(buffer,255,fp);//push string of fp to buffer 
     fputs(buffer, stdout); //outputting string from buffer to stdout 
    } 
    return(0); 
} 

+0

Чтобы узнать, как сделать цикл чтения, см. Http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong –

ответ

-1

Может быть, потому что вы открываете файл только для чтения:

fp = fopen("file.txt", "r"); /*open a file with only read mode*/ 
+0

i изменено на «r +», но результат не изменяется. Я использую eclipse в Windows –

+0

Этот ответ просто неверен. См. Ответ monkeyStrix для объяснения, почему. 'ungetc' не пытается изменить файл. –

0

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

Также, важно отметить, что ungetc влияет только на поток, а не файл:

Обратите внимание, однако, что это влияет только на дальнейшие операции ввода на этом потоке, а не содержание связанный с ним физический файл, , который не модифицируется никакими вызовами этой функции. (cplusplus.com)

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

символов Толкаемых-назад будут возвращены в обратном порядке; гарантируется только одно нажатие. (linux manual)

+0

Большое вам спасибо! Я знаю, что файл не изменяется, только поток просто меняется. Но почему мой код работает не так? и есть ли проблема, когда я использую ungetc()? –

+0

вы можете переписать мой код, но по-прежнему использовать функцию ungetc()? спасибо. –

+0

спасибо! Я заменил fgets (buffer, 2, fp); и fputs (buffer, stdout); printf ("% c", fgetc (fp)); и результат является истинным –

2

Логика в цикле while ошибочна.

Это то, что происходит:

Вы getc первый символ, a.

a не является ! поэтому вы ungetca назад на поток.

Затем вы читаете целую строку. Конечно, вы получаете abc!!!.

Затем вы печатаете линию. Выход: abc!!!.

Если вы хотите, чтобы манипулировать им строку лучше управлять буфером вместо того, чтобы пытаться изменить поток:

int i; 
    int len = fgets(buffer,255,fp);//push string of fp to buffer 
    for (i=0; i < len; i++) { 
     if (buffer[i] == '!') { 
      buffer[i] = '+'; 
     } 
    } 
    fputs(buffer, stdout); //outputting string from buffer to stdout 

В качестве альтернативы, если вы действительно хотите использовать ungetc, вам нужно прочитать/печатайте по одному символу за раз, потому что ungetc можно сделать безопасно только на одном символе. Держите if и ungetc и заменить fgets/fputs следующим:

fgets(buffer,1,fp);  // Read one character. 
    printf("%c", buffer[0]); // output one character from buffer to stdout 
+0

большое вам спасибо! но я хочу использовать функцию ungetc(). У вас есть другой способ, который по-прежнему использует функцию ungetc()? –

+0

@ThuanTran Как указывает monkeyStix, вы можете безопасно «ungetc» одного персонажа. Поэтому вам нужно читать и печатать один символ за раз, если вы хотите использовать 'ungetc'. Я добавил альтернативу в свой ответ. –

+1

спасибо! Я заменил fgets (buffer, 2, fp); и fputs (buffer, stdout); printf ("% c", fgetc (fp)); , и результат верен –

0

Вы просто контролировать первый символ файла и контролировать, что если это ! или нет, то вы читаете 255 байт из этого потока и промойте его выходной поток.

Для ввода файла (который находится в вашем примере abc!!!) после считывания 255 байтов из этого файла make feof() возвращает True и прерывает ваш цикл, потому что читать нечего.

Смежные вопросы