2011-08-10 12 views
2

私はコマンドラインからのユーザ入力を受け付けるLInux/C++の簡単なコンソールアプリケーションを作成しています。スレッド内でstd::getline(std::cin)/std::cin >> textを使用しています。stdinからの読み込みを停止

10秒後、私はコンソール入力の受け入れをやめてテキストメッセージを書き、その後他のことをしたいと思います。私はタイマーのための別のスレッドを使用しています。

ユーザーがテキストを挿入しない限り、10秒が経過したことを確認できないため、この方法は機能しません。

テキストを受け入れるアプリケーションを停止して別の行に移動する方法はありますか?私はsettimerと信号のプログラミングを使用すると思っていましたが、簡単にするために別のスレッドから何かを呼びたいと思います。

よろしく

AFG

+2

では、新しいスレッドで入力を読み込み、その後、10秒経過した後にメインスレッドからそのスレッドを殺すことはできますか? – GWW

+1

@ GWWの提案以外に、低レベルのOS機能をいつでも使用できます。 Linux/* nixでは、これを "生の" I/Oと呼びます。しかし、私はそれ以来長い時間がかかりました。 –

答えて

5

あなたはncursesを使用することができますか、このblog postで説明するように、あなたが選択し使用することができますしない場合。基本的には、selectを使用してタイムアウトを指定できます。 stdin FDが設定されている場合は、それを安全に読み取ることができ、ブロックされません。選択についての詳細は、this outともちろんWikipediaをチェックしてください。それは知るための便利な呼び出しです。例えば、

// if != 0, then there is data to be read on stdin 

int kbhit() 
{ 
    // timeout structure passed into select 
    struct timeval tv; 
    // fd_set passed into select 
    fd_set fds; 
    // Set up the timeout. here we can wait for 1 second 
    tv.tv_sec = 1; 
    tv.tv_usec = 0; 

    // Zero out the fd_set - make sure it's pristine 
    FD_ZERO(&fds); 
    // Set the FD that we want to read 
    FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0 
    // select takes the last file descriptor value + 1 in the fdset to check, 
    // the fdset for reads, writes, and errors. We are only passing in reads. 
    // the last parameter is the timeout. select will return if an FD is ready or 
    // the timeout has occurred 
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv); 
    // return 0 if STDIN is not ready to be read. 
    return FD_ISSET(STDIN_FILENO, &fds); 
} 

もスレッドがこのためにやり過ぎであるPeek stdin using pthreads

+0

うわー。私は面白いものを読んでいるようです。どうもありがとう。私は、面倒なことをやってみることもありますが、面白いこともたくさんできるようです。お知らせいたします。 –

+0

こんにちは!私は少し遅れてテストしました。それは動作しますが、kbhit()の後にバッファを消費するコードが必要です。私は以下のように答えました。どうもありがとう! –

2

でこのSO質問を参照してください。入力ループでselect()を使用して、stdinの読み込み準備が整っているかどうかを判断します。 time()の呼び出しによって時刻を確認し、10秒が経過するとループを終了することができます。

0

これはうまく動作しますが、バイトを '消費する'コードが必要です。あなたのkbhit()の使用以下

int main(int argc, const char** argv){ 
    while(!kbhit()){ 
     // do whatever you want here while 
     // entering the text 
     std::cout << "..while you write!" << std::endl; 
    } // stops when you hit 'ENTER' 
    std::string line; 
    std::getline(std::cin, line); // consume/stores into line 
    // what was written until hitting 'ENTER' 
} 
関連する問題