【问题标题】:Reading user input into array up to its maximum size将用户输入读取到数组中,直到其最大大小
【发布时间】:2020-07-29 06:43:46
【问题描述】:

假设数组的max_size 是100,我试图将scanf 用户输入到数组中,直到输入EOF。当函数检测到 EOF 时,scanf 停止并返回到目前为止输入的元素数。

int read_ints_from_stdin(int array[], int max_array_size) { 
    int i = 0, num;
    while ((scanf("%d", &num) != EOF) && i < max_array_size) {
        array[i++] = num;
        printf("value of i is: %d \n", i);
    }
    return i;
}

但是,i 一直在增加,直到 max_array_size 并且即使我输入了 EOF,该函数也始终返回 100。谁能帮我解决这个问题?

编辑:显然,我将随机值存储到我的数组中,而不是用户输入的内容。

【问题讨论】:

  • EOF 在 stdio.h 中定义(通常为 -1)。在 linux 上,ctrl+d 发出 EOF 信号,而在 Windows 上,ctrl+z 通过 shell 发送到进程 stdin。你做了其中之一吗?
  • 我实际上在我的系统上打印了 EOF,它给了我 -1。所以我一直在我的输入中使用 -1 作为 EOF
  • "我已经进入 EOF" 怎么办?你到底输入了什么?请注意,如果您键入一个非数字,scanf 将返回 0 并将有问题的字符留在流中,因此它永远不会返回 EOF。我在这里建议== 1 而不是!= EOF

标签: c scanf stdio


【解决方案1】:

首先,让我们澄清一件事:没有这样的东西作为EOF 字符。 EOF是否作为角色存在,您将能够“输入EOF”或“阅读EOF”。 EOF 只是一个任意整数常量,一个库定义的抽象,库函数使用它来表示已到达文件末尾或发生错误。就是这样。

如果您想确保自己所做的事情有意义,请查看scanf manual page

RETURN VALUE
   On success, these functions return the number of input items
   successfully matched and assigned; this can be fewer than provided
   for, or even zero, in the event of an early matching failure.

   The value EOF is returned if the end of input is reached before
   either the first successful conversion or a matching failure occurs.
   EOF is also returned if a read error occurs, in which case the error
   indicator for the stream (see ferror(3)) is set, and errno is set to
   indicate the error.

阅读以上内容,很明显scanf 不仅在到达文件末尾时返回EOF。此外,scanf 可以返回0,如果没有发生错误但没有匹配到,在这种情况下你也应该停止阅读。

在这种情况下,您要做的是使用简单的for 循环,并检查scanf 是否返回1,这是您唯一可以接受的值。如果不是,则到达文件末尾、发生错误或输入与格式字符串不匹配:检查错误并采取相应措施。不要压缩 while 条件中的所有错误检查逻辑,这只会令人困惑且难以正确处理。

这是一个工作示例,错误检查可能比您实际需要的还要多,但这只是为了说明问题。

size_t read_ints_from_stdin(int array[], size_t max_array_size) { 
    size_t i;

    for (i = 0; i < max_array_size; i++) {
        int res = scanf("%d", &array[i]);
        
        if (res != 1) {
            if (res == EOF) {
                if (feof(stdin)) {
                    // End of file reached, not an error.
                } else {
                    // Real error, print that out to stderr.
                    perror("scanf failed"); 
                }
            } else {
                // Input matching failure.
                fputs("Input does not match requested format.\n", stderr);
            }
            
            break;
        }
    }
    
    return i;
}

另外,请注意在需要时使用size_t 而不是int。在处理大小或索引时,您不希望因负值而导致错误。

【讨论】:

    【解决方案2】:

    您需要将您的 while 循环条件修改为如下内容:

    int read_ints_from_stdin(int array[], int max_array_size) { 
        int i = 0, num;
        while ( i < max_array_size) {
            scanf("%d", &num);
            if(num == EOF) break;
            array[i++] = num;
            printf("value of i is: %d \n", i);
        }
        return i;
    }
    

    您应该将 number 的值与 EOF 进行比较,而不是 scanf 返回的值。这是因为,scanf 返回分配的成功输入的数量。在您的代码中,每次迭代时,scanf 始终返回 1(因为该值已分配给 num),稍后将其与 EOF(扩展为 -1)进行比较

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-16
      • 2016-02-10
      • 1970-01-01
      相关资源
      最近更新 更多