2011-07-27 6 views
13

stdinに入力があるかどうかをテストしたいと思います。私はうまくいくソリューションを見つけましたが、彼らは醜いですし、自分のソリューションがきれいであることが好きです。 Linux上でstdinにC++(Windowsおよび/またはLinux)の入力があるかどうかテストしてください

私はこれを使用します。

bool StdinOpen() { 
    FILE* handle = popen("test -p /dev/stdin", "r"); 
    return pclose(handle) == 0; 
} 

私は、私はより多くのエラー処理を追加する必要があることを知っているが、それはポイント以外にもあります。私はこれを使用してWindows上で

bool StdinOpen() { 
    static HANDLE handle = GetStdHandle(STD_INPUT_HANDLE); 
    DWORD bytes_left; 
    PeekNamedPipe(handle, NULL, 0, NULL, &bytes_left, NULL); 
    return bytes_left; 
} 

Linux用の罰金ですが、私は私が(test -f $fileのためのように、あなたがfopen($file, "r") != NULLを行う)パイプを使用せずに呼び出すことができます同等のAPIであるかを知りたいこと。私はopen("/dev/stdin", "r")と同じことをすることができますが、私はそれを行うための最善の方法を知りたいと思います。

概要:あなたは窓のためのよりよい解決策を知っていれば、私は、私がLinux用test -p /dev/stdinの代わりに使用できるAPIを知りた​​い、と。

+0

標準入力が(パイプではなく)ファイルハンドルである場合、あなたの 'PeekNamedPipe'ソリューションは失敗します。また、 'handle'変数は静的であってはいけません。あなたのアプリケーションの実行中にハンドルがリダイレクトされた場合は、後で自分自身を驚かせるでしょう。 –

+0

@Billy:私はハンドルがランダムにリダイレクトされるとは思わない。確かに、あなたは何をstdinと考えるかを変えるかもしれないが、古いハンドルはまだそこにある。しかし、私は最初の部分について同意します。 – Mehrdad

+0

Lionel BはLinux用のコードをhttp://bytes.com/topic/c/answers/841283-how-make-non-blocking-call-cinで提供しています。 –

答えて

13

これはPOSIX(Linux)の解決策です:私はWindows上でpoll()と同等のものがよく分かりません。 Unixでは、番号0のファイル記述子が標準入力です。

#include <stdio.h> 
#include <sys/poll.h> 

int main(void) 
{ 
     struct pollfd fds; 
     int ret; 
     fds.fd = 0; /* this is STDIN */ 
     fds.events = POLLIN; 
     ret = poll(&fds, 1, 0); 
     if(ret == 1) 
       printf("Yep\n"); 
     else if(ret == 0) 
       printf("No\n"); 
     else 
       printf("Error\n"); 
     return 0; 
} 

テスト:

$ ./stdin 
No 
$ echo "foo" | ./stdin 
Yep 
+0

これはまさに私が欲しかったものです。入力バッファーのサイズを測定する方法を教えてもらえれば永遠に感謝しますが、私は質問ホッグのように聞こえたくありません。 – norcalli

+0

read()を使用して入力を取得できます。最初にfcntl()を使用してファイル記述子0を非ブロックに設定すると、read()は読み取られたバイト数を返し、それ以上のデータがない場合は0を返します。 – Antti

+2

+1。よく使われるもう1つの選択肢は 'select()'です。これは概念的に似た使い方です。ディスクリプタから新しいデータが利用できるかどうかをオペレーティングシステムに問い合わせることが重要です。そのレベルで操作している場合は、ディスクリプタで直接 'read()'を使用する必要があります。 (新しいバッファ実装を提供しない限り) 'std :: cin'を使用してください。 –

1

私はよく分かりませんが、_kbhit()は必要な作業を行いますか?

1

が、この作品ではないでしょうか?

std::cin.rdbuf()->in_avail(); 
関連する問題