我正在研究输入/输出文件。下面的代码涉及一些函数,如: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);
}
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个字节,并将其刷新到输出流。
对于输入文件(在您的示例中是abc!!!
),在从该文件读取255个字节后,使feof()返回True并中断循环,因为没有什么可读取的。
正如另一个答案所指出的,错误发生了,因为你只测试文件中的第一个字符,然后从中读取255个字节,而不是一次获取一个字节并测试它
另外,需要注意的一点是ungetc只影响流而不影响文件:
不过,请注意,这只会影响对流而不是与其相关联的物理文件的内容,对该函数的任何调用都不会修改它。(cplusplus.com)
此外,如果功能仅保证连续使用一次:
被推回的字符将以相反的顺序返回;只保证一次推回。(linux手册)
也许,因为您以只读方式打开文件:
fp = fopen("file.txt", "r"); /*open a file with only read mode*/