std::cin 在不应该接收输入时接收输入

std::cin recieving input when it shouldn't

本文关键字:输入 不应该 cin std      更新时间:2023-10-16

我最近在使用std::cin时遇到了一个问题,当我尝试将其与std::this_thread::sleep_for()结合使用时,它甚至在尚未调用时就开始获得输入。

这是我一直在使用的代码:

#include <iostream>
#include <chrono>
#include <thread>
#include <string>
using std::string
using namespace std::this_thread
using namespace std::chrono
int main(){
    string a;
    sleep_for(seconds(3)); //start typing around now
    std::cin >> a;         //the text typed during the sleep_for() shows up now
    return 0;
}

当您在sleep_for()期间开始键入时,文本只会在调用std::cin之后显示。我想知道是否有人知道如何修复它,以及为什么会发生这种情况。

出现这种情况的原因是涉及两个组件,它们独立运行:

  • 第二个组成部分是你的程序。它通常所做的只是内部事务以及通过stdin、stdout和stderr与外部的通信
  • 第一个组件是控制台(终端[模拟器]、命令行、DOS框……有各种名称),它实际上显示程序的输出,并从键盘接收程序的输入

控制台独立工作,这意味着即使您的程序还没有请求输入,它也会为您的程序收集输入。这个输入被缓冲并发送到你的程序,当你要求它时,你会在那里收到它

现在,你能做些什么?首先,您可以编写自己的控制台,使其按照自己的意愿运行,但这绝非易事。其次,还有一些方法可以通过所谓的转义序列与控制台进行通信。例如,这些序列允许您显示颜色或粗体字体,但它们不是标准化的,因此它们取决于控制台,因此获得可靠的结果也很重要。然而,也有类似的库,例如"curses"和其他类似名称的库。这些甚至允许您在控制台中创建基于文本的窗口,这些窗口应该是可以查看的

在Linux中,您可以执行以下操作:

...
std::cin >> a;         //the text typed during the sleep_for() shows up now
cout << "e[A";. // move cursor up
for(size_t i=0; i<a.size(); i++){
    cout << "b b"; // erase one character
}

也就是说,在Linux上sleep_for不会阻止键入的文本立即显示。

我不确定是否有等效于向上移动光标的窗口。