【问题标题】:Scanf returns EOF unexpectedlyScanf 意外返回 EOF
【发布时间】:2020-04-21 05:03:13
【问题描述】:

我的代码有什么问题? 当给出以下输入(通过文件)时:

6.02
110 223 144 208 199.5 890
200 69.5 300 138.7 190 601

它打印ERROR: invalid price in airline # 1,但它不应该这样做。 这是我的代码。

int fillPricesTable(double flightsPrices[][DEST],int n,double* dollarRate)
{
    //n is the number of rows
    double Price;
    int  AirLinesCounter=0;
    while (scanf("%lf",dollarRate)==EOF || *dollarRate<=0)
    {
        errorDollar();
        fflush(stdin);
    }
    for (int i=0;i<n;++i)
    {
        for (int j=0;j<6;++j)
        {
            if (scanf("%lf",&Price)==EOF || Price<=0)
            {
                printf("ERROR: invalid price in airline # %d\n", i);
                return -1;
            }
            flightsPrices[i][j]=Price;
        }
        AirLinesCounter++;
        if(scanf("%lf",&Price)==EOF)
            break;
    }
    return AirLinesCounter;
}

【问题讨论】:

  • n 是什么?请创建一个minimal, reproducible example 并用它更新您的问题。
  • 注意Using fflush(stdin) 的语义——它至少是不可移植的。
  • 在标准输入上刷新未定义
  • 不是您要问的实际问题,而是一般提示:scanf 也可以返回 0。查看文档以了解这意味着什么。考虑一下您的代码在scanf 确实返回 0 的情况下会做什么。
  • @hyde 按照建议更新了我的代码,但仍然是相同的错误

标签: c scanf c99 eof io-redirection


【解决方案1】:

由于for (int j=0;j&lt;6;++j) 循环体之后的if(scanf("%lf",&amp;Price)==EOF)AirLinesCounter++ 之后的那个),您在i 的每个循环中扫描一个数字太多。

只需将第二个if 与正文一起删除即可。

fflush(stdin); 在技术上是未定义的行为。要从输入中读取缓冲数据,循环 getchar() 直到出现换行符或 EOF。

您可以例如删除第二个 if,例如在错误中添加一个条件来处理单独扫描行中第一个数字的错误:

int fillPricesTable(double flightsPrices[][DEST], int n, double *dollarRate)
{
    while (scanf("%lf", dollarRate) != 1 || *dollarRate <= 0) {
        errorDollar();
        for (int i; (i = getchar()) != '\n' && i != EOF;);
    }

    bool end_me = false;
    int i = 0;
    for (i = 0; i < n && end_me == false; ++i) {
        for (int j = 0; j < 6; ++j) {
            // no need to scan into temporary variable
            // just scan into the destination
            if (scanf("%lf", &flightsPrices[i][j]) != 1 || flightsPrices[i][j] <= 0)  {
                if (j == 0) {
                    // this is first number in the row
                    end_me = true; // using separate variable to end the outer loop
                    // because C does not have "break 2" or similar.
                    break;
                } else {
                    errorPrice(i);
                    return -1;
                }
            }
        }
    }
    return i; // AirLinesCounter is equal to i....
}

【讨论】:

  • 但是第二个 if 应该只在文件末尾输入,因为它只有在读取一行中的所有 6 个值后才会兴奋
  • @Daniel98 — 行尾与文件尾不同。内部循环在读取 6 个值后终止(或者如果之前遇到 EOF)。
  • 我也看到了同样的情况。对于所示的输入示例和 n 的值为 2,您的输入值“200”将被丢弃,使其仅在第二行看到 6 个值中的 5 个。
  • @BobShaffer 我已经更新了我的代码,你能看看我的代码有什么问题吗?它应该 100% 正常工作我现在看不到任何错误!
  • 删除if(scanf("%lf",&amp;Price)==EOF) break;... 您正在为每个for (i=0;i&lt;n;++i) 循环执行7 scanf 调用,因此每个循环扫描7 个数字。由于每行有 6 个数字,第二次只剩下 5 个数字要扫描,所以扫描第 6 个数字失败。
猜你喜欢
  • 2020-02-23
  • 1970-01-01
  • 1970-01-01
  • 2017-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-16
相关资源
最近更新 更多