繁体   English   中英

如何在特定时间后从 `std::cin` 超时读取

[英]How to make reading from `std::cin` timeout after a particular amount of time

我写了一个小程序,

int main(int argc, char *argv[])
{
    int n;
    std::cout << "Before reading from cin" << std::endl;

    // Below reading from cin should be executed within stipulated time
    bool b=std::cin >> n;
    if (b)
          std::cout << "input is integer for n and it's correct" << std::endl;
    else
          std::cout << "Either n is not integer or no input for n" << std::endl;
    return 0;
 }

std::cin读取是阻塞的,因此程序会一直等待,直到程序有外部中断(也像信号)或用户提供一些输入。

我应该如何为用户输入声明std::cin >> n等待一段时间(可能使用sleep()系统调用)? 如果用户没有提供输入,并且在规定的时间(比方说 10 秒)完成后,程序应该继续执行下一条指令(即if (b==1)语句开始)。

这对我有用(请注意,但是这在Windows下不起作用):

#include <iostream>
#include <sys/select.h>

using namespace std;

int main(int argc, char *argv[])
{
    int n;
    cout<<"Before performing cin operation"<<endl;

    //Below cin operation should be executed within stipulated period of time
    fd_set readSet;
    FD_ZERO(&readSet);
    FD_SET(STDIN_FILENO, &readSet);
    struct timeval tv = {10, 0};  // 10 seconds, 0 microseconds;
    if (select(STDIN_FILENO+1, &readSet, NULL, NULL, &tv) < 0) perror("select");

    bool b = (FD_ISSET(STDIN_FILENO, &readSet)) ? (cin>>n) : false;

    if(b==1)
          cout<<"input is integer for n and it's correct"<<endl;
    else
          cout<<"Either n is not integer or no input for n"<<endl;

    return 0;
}

使用标准C或C ++函数无法做到这一点。

有很多使用非标准代码的方法,但是您很可能不得不将输入作为字符串或单独的按键进行处理,而不是像cin >> x >> y;那样读取输入cin >> x >> y; 其中xy是任何C ++类型的任意变量。

实现此目的的最简单方法是使用ncurses库-特别是在Linux上。

timeout功能将允许您设置超时(以毫秒为单位),并且可以使用getstr()读取字符串,或使用scanw()读取C scanf样式输入。

我有一个坏消息:cin不是陈述。 它是std :: istream类型的对象,它将对象默认映射到操作系统默认映射到程序控制台的标准输入文件。

什么不是cin,而是用空缓冲区读取标准输入时控制台本身调用的控制台行编辑器。

您要问的问题超出了标准输入模型cin的包装范围,并且不能实现为istream功能。

唯一的干净方法是使用控制台的本机I / O功能来获取用户事件,并且-最终-仅在解析了某些字符之后才依赖C ++流。

基于 c++ 标准的干净解决方案,它是跨平台的,紧凑且可重复用于 c++11 标准和更新版本

#include <iostream>
#include<thread>
#include<string>


class Time_Limited_Input_Reader{ 
public:
   std::string Input;
   void operator()(){
    Time_Limited_Input_Reader Input_Reader; 
    std::cout<<"enter inp"<<std::endl;
    std::thread Read_Input(&Time_Limited_Input_Reader::Read,this);
    Read_Input.detach();
    std::this_thread::sleep_for(std::chrono::seconds(5));
    Read_Input.~thread();
   }
private:
   
   void Read(){
       Input = "nothing entered";
       
       std::cin>>Input;
       
   }
};
int main(){
   
   Time_Limited_Input_Reader Input_Reader;
   Input_Reader();
   std::cout<<"Input Data : "<<Input_Reader.Input<<std::endl;
}

可能有用:

  auto read_input = [&]() {
    std::string input;
    std::cin >> input;
    return input;
  };

  std::future<std::string> future_input;
  while (1) {
    if (!future_input.valid())
      future_input = std::async(read_input);

    if (future_input.wait_for(std::chrono::milliseconds(1000)) == std::future_status::ready) {
      std::string s = future_input.get();
      if (s == "q") {
        break;
      }
    }
  }
  

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM