【问题标题】:Why the input "abc!!!" but the output is not "abc+++"? [closed]为什么输入“abc!!!”但输出不是“abc++”? [关闭]
【发布时间】:2016-07-25 07:41:50
【问题描述】:

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

【问题讨论】:

标签: c file fgets fputs ungetc


【解决方案1】:

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

【讨论】:

  • 非常感谢!但我想使用 ungetc() 函数。您还有其他方法仍然使用 ungetc() 函数吗?
  • @ThuanTran 正如 monkeyStix 指出的那样,您只能安全地 ungetc 一个字符。因此,如果您想使用ungetc,则需要一次读取和打印一个字符。 Se 在我的回答中添加了替代方案。
  • 谢谢!我替换了 fgets(buffer,2,fp);和 fputs(缓冲区,标准输出);到 printf("%c",fgetc(fp));结果是真的
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

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

    另外,如果只保证连续使用一次的功能:

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

    【讨论】:

    • 非常感谢!我知道那个文件没有变化,只有流只是改变。但是为什么我的代码运行不正确?当我使用 ungetc() 时有问题吗?
    • 你能重写我的代码但仍然使用 ungetc() 函数吗?谢谢。
    • 谢谢!我替换了 fgets(buffer,2,fp);和 fputs(缓冲区,标准输出);到 printf("%c",fgetc(fp));结果是真的
    【解决方案4】:

    也许,因为您以只读方式打开文件:

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

    【讨论】:

    • 我改为“r+”,但结果没有改变。我在 Windows 中使用 eclipse
    • 这个答案是完全错误的。请参阅 monkeyStrix 答案以了解原因。 ungetc 不会尝试修改文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 2013-09-21
    • 2020-07-14
    • 2013-06-05
    相关资源
    最近更新 更多