10

我写了一个小程序,

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)语句开始)。

4

5 回答 5

10

这对我有用(请注意,这在 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;
}
于 2013-08-31T20:06:05.707 回答
4

There is no way to do this using standard C or C++ functions.

There are a number of ways using non-standard code, but you will most likely have to deal with input either as a string or individual keypresses, rather than being able to read input like cin >> x >> y; where x and y are arbitrary variables of any C++ type.

The easiest way to achieve this would be to use the ncurses library - in particular as you are on Linux.

The timeout function will allow you to set a timeout (in milliseconds) and you can use getstr() to read a string, or scanw() to read C scanf style input.

于 2013-08-31T19:43:42.340 回答
4

I have a bad news for you: cin is NOT A STATEMENT. It is an object of type std::istream that remaps the standard input file that your OS maps by default to your program's console.

What blocks is not cin, but the console line editor that the console itself invokes when the standard input is read with an empty buffer.

What you are asking goes ahead of the standard input model cin is supposed to wrap, and cannot be implemented as a istream functionality.

The only clean way to do it is using the native I/O functionality of the console, to get user events, and -eventually- rely on C++ streams only after you've got some characters to be parsed.

于 2013-08-31T19:44:58.453 回答
0

可能有用:

  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;
      }
    }
  }
  
于 2021-10-10T09:45:56.097 回答
0

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

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


class Timee_Limited_Input_Reader{ 
public:
   std::string Input;
   void operator()(){
    Timee_Limited_Input_Reader Input_Reader; 
    std::cout<<"enter inp"<<std::endl;
    std::thread Read_Input(&Timee_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(){
   
   Timee_Limited_Input_Reader Input_Reader;
   Input_Reader();
   std::cout<<"Input Data : "<<Input_Reader.Input<<std::endl;
}
于 2021-10-10T11:34:30.013 回答