【问题标题】:Get text while not EOF获取文本而不是 EOF
【发布时间】:2015-12-05 19:52:13
【问题描述】:

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define N 256

int main(int argc, const char * argv[]) {

    char testo[N];
    int i;
    printf("PER TERMINARE L'INSERIMENTO PREMERE CTRL+Z oppure CTRL+D \n");
    for(i=0;i<N;i++)
    {
        scanf("%c",&testo[i]);
        /* if(testo[i]=='h' && testo[i-1]=='c')
        {
            i--;
            testo[i]='k';
        }
        if(testo[i]==testo[i-1])
        {
            i--;
        } */
        if(testo[i]==EOF)
        {
            break;
        }
    }

    puts(testo);

    return 0;
}

编译/* ... */ 中的代码时,我无法停止使用EOF 插入文本,但是当代码按照此处所示构建并运行时,EOF 可以工作。

有人知道问题出在哪里吗?

【问题讨论】:

  • 更好的是,使用getline 或至少fgets 阅读整行
  • if (testo[i] == EOF) 巧合地工作是类型 char 类型已签名。在读取字符\377时也会错误地检测到文件结尾。

标签: c string text char eof


【解决方案1】:

您正在错误地测试 EOF。使用scanf(),需要查看返回值。事实上,几乎所有的输入函数都需要测试,如果不捕获和测试,则返回值。

表面上,你需要:

for (i = 0; i < N; i++)
{
    if (scanf("%c", &testo[i]) == EOF)
        break;
    …
}

但是,一般来说,您应该检查scanf() 是否按照您的要求进行了多次成功转换,因此最好这样写:

for (i = 0; i < N; i++)
{
    if (scanf("%c", &testo[i]) != 1)
        break;
    …
}

在这个例子中,这真的无关紧要。但是,如果您正在阅读数字数据,那将很重要。用户可能键入 Z 而不是数字,scanf() 将返回 0,而不是 EOF。

【讨论】:

    【解决方案2】:

    要检测EOF,检查scanf()的结果

    if scanf("%c",&testo[i]) == EOF) break;
    

    注意:testo[] 不能以空字符结尾。要打印为字符串,请确保它是。

    char testo[N];
    int i;
    
    // for(i=0;i<N;i++) {
    for(i=0;i<(N-1);i++) {
      if (scanf("%c",&testo[i]) == EOF) break;
    }
    
    testo[i] = '\0';  // add
    puts(testo);
    

    【讨论】:

      【解决方案3】:

      要在文件末尾停止,请检查来自scanf 的返回值:

      scanf 返回正确解析的输入数。在您的情况下,%c 只要未到达文件末尾,就会正确地从流中读取一个字节。 if (scanf("%c",&amp;testo[i]) != 1) break; 可以。

      然而,使用scanf 从输入流中一次读取一个字节是多余的。在 C 中执行此操作的惯用方法是使用 getchar()getc() 函数。返回值必须存储在int 变量中,并且在文件结束时具有特殊值EOF

      您还应该使数组长 1 个字节并在末尾存储一个空字节以使其成为 C 字符串,正如 puts 所期望的那样。

      这是您的程序的修改版本:

      int main(int argc, const char *argv[]) {
          char testo[N+1];
          int i;
      
          printf("PER TERMINARE L'INSERIMENTO PREMERE CTRL+Z oppure CTRL+D\n");
      
          for (i = 0; i < N; i++) {
              int c = getchar();
              if (c == EOF)
                  break;
              testo[i] = c;
              /* ... further processing ... */
          }
          testo[i] = '\0';
      
          puts(testo);
          return 0;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-11
        • 1970-01-01
        • 1970-01-01
        • 2013-05-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多