【问题标题】:scanf/cin is stucks in loopscanf/cin 卡在循环中
【发布时间】:2019-12-10 19:13:07
【问题描述】:

我有一个 C++ 程序,它对给定的数组大小执行计算。它在小数组上工作正常,但在大数组上,scanf 和 cin 卡住了,如果我输入任何非数字,它会跳出评估错误计算的循环。

编辑:如果我将输入分成多行,那么它可以工作。那么如何增加我的操作系统(即 Linux)的行长限制

这里是重现问题的示例代码:-

#include <iostream>

using namespace std;
int main() {
    int N;

    cin >> N;
    int *X = new int[N];

    for(int i=0;i<N;i++){
        cout << "getting " << i << "th input \n";
        cin >> X[i]; // tried scanf too but i
    }

    cout << "Done\n";

    return 0;
}

当我提供像这样的大量输入时:- https://pastebin.com/PWmm9J7i

打印直到

getting 693th input

我多次运行程序,仍然得到相同的结果。我还用 clang 和 gcc 编译了它,但它仍然停留在第 693 个输入。

我正在使用 Manjaro OS 和 ZSH shell

【问题讨论】:

  • 无法复制:ideone.com/5eBvPw
  • 代码没有问题。输入中可能有一个时髦的字符,可能在第 693 个值之后。
  • “693th”输入出现在第二行的字符位置 4096,因此您的操作系统的标准输入缓冲或您用于提供输入的方法可能不能超过 4K 行长度,或类似那 。您可以尝试在输入文件中添加一些换行符,以便没有行达到该长度
  • @M.M 你说得对。在多行上分离输入是有效的。有没有办法在 Linux 上增加这个行长限制?

标签: linux shell zsh stdin


【解决方案1】:

首先,您链接到的示例运行良好。但是你说:cin 卡住了,如果我输入任何非数字。这是预期的行为。要处理这个问题,您需要检查cin 的状态,如果它处于错误状态,请清除错误并使用坏字符:

for (int i = 0; i < N; i++){
    cout << "getting " << i << "th input \n";
    if (!(cin >> X[i])) {
        // No more input?
        if (cin.eof()) break;
        // Clear error
        std::cin.clear(); 
        // Consume all input until next space
        std::cin.ignore(std::numeric_limits<std::streamsize>::max(), ' ');
        // You probably also want to decrement i
        i--;
    }
}

【讨论】:

    【解决方案2】:

    这是cin的预期错误

    int i;
    cin>>i;
    if(cin.fail()) {
    //error handling here
    } 
    

    【讨论】:

      【解决方案3】:

      我发现它与Canonical Mode Input Processing 有关。 更多信息可以找到here

      您可以使用stty cbreakstty -icanon 关闭规范模式

      我正在使用 Zsh shell,所以我链接的网站上的答案对我不起作用。它们确实适用于 bash shell。现在,我正在使用这种技术将输入提供给程序:-

      ./program < input.txt
      

      【讨论】:

      • UUOc不必要地使用cat)。 ./program &lt; input04.txt 会更好。
      • @DavidC.Rankin 谢谢。已编辑
      • 您是一直使用./program &lt; input.txt,还是说改成该表单可以解决问题?最好更新问题以显示不起作用的方法。
      猜你喜欢
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      • 2023-04-03
      • 2012-02-21
      • 1970-01-01
      • 2016-05-18
      • 2021-12-16
      相关资源
      最近更新 更多