【问题标题】:testing scanf != EOF in a while loop failure [closed]在while循环失败中测试scanf!= EOF [关闭]
【发布时间】:2018-11-06 08:56:41
【问题描述】:

所以我开始了 C 课程,虽然我有 C# 和 C++ 方面的经验,但我已经达到了一个我很早就被困在 scanf = EOF 方面的地步

    printf("Students, please enter heights!\n");
double maleAvg = 0, femaleAvg = 0;
int currentHeight = 0, malecount = 0, femalecount = 0;
while(scanf("%d",&currentHeight) != EOF)
{
    if(currentHeight > 0)
    {
        femaleAvg += currentHeight;
        femalecount++;
    }
    else if (currentHeight < 0)
    {
        maleAvg += currentHeight;
        malecount++;
    }
    else
    {
        printf("Error! Invalid height 0!\n");
        return 0;
    }
}
if(femalecount == 0)
{
    printf("No girls in class! :(\n");
}
else
{
    femaleAvg /= femalecount;
    printf("Average girls height is: %f\n",femaleAvg);
}
if(malecount == 0)
{
    printf("No boys in class! :(\n");
}
else
{
    maleAvg /= malecount;
    printf("Average boy height is: %f\n",maleAvg);
}
return 0;

据我了解,这是创建此循环的正确方法,因此它会一直读取到文件末尾。但是,我发现虽然它确实根据写入的数字量进入循环,但在 while 循环之后它什么也不做,只是卡住了。我尝试在循环结束后立即打印一条消息,但没有打印任何内容。

【问题讨论】:

  • 你能添加更多代码吗?我会写while(scanf("%d",&amp;currentHeight) == 1),循环只要scanf 可以读取1 个整数。
  • 您的意见是什么?如果您的输入无法转换为十进制数,scanf 将返回 0 并回溯到未解析的输入之前,从而有效地创建无限循环。使用 mch 的建议或用%s 扫描一个单词,然后用strtol 解析它。
  • 阅读手册。此函数返回分配的输入项数,[如果]在转换开始后发生错误或文件结尾,则返回成功完成的转换数。试试这个: while(scanf("%d",&amp;currentHeight) == 1)
  • 请完整的minimal reproducible example 包括输入、输出、它需要做什么以及循环内的代码、变量声明等等——至少。
  • 您提到要从文件中读取,但scanf 从“标准输入通道”stdin 中读取,该通道通常以交互方式输入到控制台中。如果您不输入任何内容,程序只会等待您输入内容。你可以像这样重定向你的输入:myprog &lt; myfile 或者你可以使用fscanf,它接受一个额外的参数,打开文件,作为第一个参数。

标签: c scanf eof


【解决方案1】:

您的问题来自stdin 永远不会关闭,也永远不会在“正常”输入下返回 EOF。您可以通过键入 Ctrl+D(在 Linux 上)和 Ctrl+Z(在 Windows/ DOS):

int main(int argc, char** argv)
{
    int i;
    int s = 0;
    printf("Enter integer, Ctrl+D to compute the sum:\n");
    while (scanf("%d", &i) != EOF) {
        s += i;
    }
    printf("Sum = %d\n", s);
}

编译运行:

Enter integer, Ctrl+D to compute the sum:
1
5
4
3
Sum = 13

但是你真的应该检查返回值并进行相应的处理,因为如果你输入例如它会失败。 1.2(通常:总是检查返回值)。

请注意,正如@Toby Speight 所指出的,您还可以使用您最喜欢的发送 EOF 的 shell 从文件重定向:

./a.out < numbers.txt

numbers.txt 就像:

1
5
4
3

【讨论】:

  • IIRC,在 CP/M 和相关系统(例如 DOS)上,使用 C-z 代替 C-d。 stdin 无需按键即可轻松关闭 - 例如,只需将其连接到管道或文件。
  • @TobySpeight 当然是Ctrl+Z!我也添加了有关文件重定向的信息,谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-10-31
  • 1970-01-01
  • 2012-11-06
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
  • 2010-09-18
相关资源
最近更新 更多