Почему ввод "abc!!!" но вывод не "abC+++"?
Я исследовал файл ввода / вывода. Ниже приведен код некоторых функций, таких как: fgetc(),fgets(),fputs(). Я не знаю, почему это не работает так, как я хочу. Большое спасибо! Ниже мой код:
#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);
}
4 ответа
Логика в цикле while имеет недостатки.
Вот что происходит:
Вы getc
первый персонаж, a
,
a
это не !
так что вы ungetc
a
обратно в поток.
Затем вы читаете всю строку. Конечно получаешь 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
Ошибка возникает, как указано в другом ответе, потому что вы тестируете только первый символ в файле, а затем читаете из него 255 байт, вместо того, чтобы захватывать один байт за раз и тестировать его.
Также важно отметить, что ungetc влияет только на поток, а не на файл:
Однако обратите внимание, что это влияет только на дальнейшие операции ввода в этом потоке, а не на содержимое физического файла, связанного с ним, который не изменяется никакими вызовами этой функции. (Cplusplus.com)
Кроме того, функция гарантирована только для одного последовательного использования:
Задержанные символы будут возвращены в обратном порядке; гарантирован только один возврат. (руководство по Linux)
Вы просто контролируете первый символ файла и контролируете, что если он !
или нет, тогда вы читаете 255 байтов из этого потока и сбрасываете его в выходной поток.
Для входного файла (который abc!!!
в вашем примере) после чтения 255 байт из этого файла make feof() возвращает True и прерывает ваш цикл, потому что читать нечего.
Возможно, потому что вы открываете файл только для чтения:
fp = fopen("file.txt", "r"); /*open a file with only read mode*/