为什么输入“abc !!!”但输出不是“abc +++”?

时间:2016-07-25 07:41:50

标签: c file fgets fputs ungetc

我研究输入/输出文件。下面的代码涉及一些函数,例如: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 个答案:

答案 0 :(得分:2)

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只能在一个字符上安全地完成。保留ifungetc,并将fgets/fputs替换为以下内容:

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

答案 1 :(得分:0)

正如另一个答案所指出的,错误发生了,因为你只测试文件中的第一个字符,然后从中读取255个字节,而不是一次抓取一个字节并进行测试。

另外,需要注意的一点是,ungetc只影响流而不影响文件:

  

但请注意,这仅影响其他输入操作   流,而不是与之关联的物理文件的内容,   任何对此函数的调用都不会修改它。   (cplusplus.com)

此外,该功能仅保证连续使用一次:

  

推回的字符将以相反的顺序返回;只保证一次回击。   (linux手册)

答案 2 :(得分:0)

您只需控制文件的第一个字符并控制它是否为!,然后您从该流中读取255个字节并将其刷新到输出流。

对于输入文件(在您的示例中为abc!!!),在从该文件读取255个字节后,make feof()返回True并断开循环,因为没有什么可读的。

答案 3 :(得分:-1)

也许,因为你打开文件只读:

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