继续征求意见并重新打开 stdin

Keep asking for input and reopen stdin

提问人:Dzamba 提问时间:12/11/2020 更新时间:12/11/2020 访问量:131

问:

我有一个任务是创建一个程序,对数字向量进行一些计算。向量中必须包含至少 1 个数字,如果没有,我必须抛出异常并重试。这里有一个视频示例,代码应该如何工作:https://asciinema.org/a/283343

我猜 EOF 是使用 CTRL+D 发出信号的,这就是导致抛出异常的原因。 如果他们使用 Enter(换行),它会留下一个空行。 但在我的情况下,在我按下 CTRL+D 后,我的程序只是在无限循环中运行,因为尽管我使用了 cin.clear(),但 stdin 仍处于失败状态。

是否有另一个类似于 CTRL+D 的快捷方式可能用于此目的,或者是否有办法重新打开流或重新启动整个应用程序。

当我使用 CTRL+Z 时,该程序在 Windows 上运行良好,但在 Linux 上我无法让它以相同的方式工作。

示例代码如下:

#include<iostream>
#include<vector>

void enter_elements(std::vector<double>& input_list){
    double x;
    std::cout << "Enter numbers: " << std::endl;
    while(std::cin >> x){
        input_list.push_back(x);
    }
    if(input_list.empty()){
        throw std::string("You must enter at least 1 number!");
    }

}

int main(){
    std::vector<double> input_list;

    try {
    enter_elements(input_list);
    } catch (const std::string& e) {
        std::cout << "Error: " << e << std::endl;
        std::cin.clear();
        enter_elements(input_list);
    }
    return 0;
}

谁能帮我解决这个问题,或者建议我在哪里可以阅读更多关于它的信息?

C++ 标准 EOF

评论

1赞 Some programmer dude 12/11/2020
我脑海中浮现的两件事:首先,这似乎不是异常的好用例;第二件事是,您可能希望使用特殊的哨兵输入来标记输入的末尾而不是文件末尾。
0赞 Some programmer dude 12/11/2020
哦,还有第三件事:你可能想在循环中调用,直到向量不为空。现在你只做了两次尝试。enter_elements
0赞 Dzamba 12/11/2020
我正在考虑调用 main() 而不是 enter_elements(list),这样我基本上可以“重新启动”我的程序。
1赞 Some programmer dude 12/11/2020
哦,你不能那样做。在 C++ 中禁止自己调用 main,这会导致未定义的行为。如果需要循环,请使用实际循环。

答:

0赞 Jean-Benoit Harvey 12/11/2020 #1

你在问如何停止程序吗?
如果是这样,在 Linux 上,您应该尝试而不是在程序运行时或在程序运行时尝试
CTRL+CCTRL+DCTRL+Z

0赞 Joseph Larson 12/11/2020 #2

这就是我讨厌使用 cin >> anInt 的原因。我更喜欢 getLine 并自己解析它。然后你可以让它做任何事情,并决定你将如何确定列表的末尾,等等。

是的,它更多的代码。但你不会遇到这样的奇怪问题。

评论

0赞 Dzamba 12/11/2020
我尝试走这条路,但是,当我发出 CTRL+D 信号时,即使使用 std::cin.ignore() 后,std::cin 仍保持失败状态,并且程序进入无限循环。
0赞 Joseph Larson 12/11/2020
没错,这就是为什么你需要一种不同的方式来结束你的输入——比如一个空行。
1赞 Asteroids With Wings 12/11/2020 #3

不。

关闭流后,流将关闭。就是这样。

我要做的是在一行上接受一组数字。您的输入迭代将在行的末尾结束。然后验证这些数字,并在必要时要求另一行。

您可以通过循环而不是使用格式化提取来做到这一点。然后,您需要解析您得到的行。std::getline

这不是视频显示的内容,但我不知道他们是如何做到这一点的。也许你应该问他们!