2017-01-09 7 views
1

getline()を呼び出す方法はありますか?入力がない場合はブロックして待機しませんか?入力をブロックしないでgetlineを使用するにはどうすればよいですか?

私は次のコードを持っている:

while(true){ 
    if(recv(sd, tBuffer, sizeof(tBuffer), MSG_PEEK | MSG_DONTWAIT) > 0) break; 
    getline(cin,send); 
} 

を私は入力を待ちたいが、私はsdソケットでいくつかのデータを受信した場合、私はデータを待って停止し、whileを終了します。今すぐ私のコードは、ちょうどgetline()で最初の反復に立ち往生。 getline()を評価したい場合は、入力がない場合はifに戻ります。

これは可能ですか?

PS:私はcin.peek()で試しましたが、入力用にブロックしました。あなたは、標準入力の非ブロックモード、ファイルディスクリプタ0に設定することによってこれを行うことができるはず

+1

質問に答えるには:はい、可能です。少なくともLinuxでは。 –

+0

私はUbuntuを使っています。どうしたのですか?あなたは私にいくつかのリンクを与えたり、私に説明したりできますか? – Darius

+1

短い答えは:1) 'getline'ではなく、低レベルのI/Oを使います。 2) 'select'を使います。 –

答えて

3

int flags = fcntl(0, F_GETFL, 0); 
fcntl(0, F_SETFL, flags | O_NONBLOCK); 

を利用可能な入力がありません場合は、基礎となるread()システムコールは0を返し、 std::cinはこれがファイルの最後であると考えて、eof()std::cinに設定します。

標準入力から再度読み込みたい場合は、ストリームの状態をclear()にします。

ここで唯一複雑な要因は、実際のファイル終了条件をstd::cinで検出することが困難になることです。標準入力が対話型端末である場合にはあまり問題はありません。標準入力がファイルである場合、これは問題になるでしょう。その場合

、あなたの唯一の現実的な選択肢はread()そして、それを読むために何かがあるときを決定するために、select()それを、完全にstd::cinを見送るファイルディスクリプタ0で非ブロックモードを入れ、poll()かすることです。

ことは、明らかに、あらゆる種類のを先取りしまうので、あなたは、すでにstd::cin年代streambufにバッファリング何があるかどう明示的に確認する必要がありますので、あなたも、これは複雑に取得する予定です、std::cinpoll()またはselect()を使用することができますが、 poll()またはselect()チェック。 std::cinから何かを読み込もうとすると、まだバッファリングされたデータを読み込み、次に非ブロックモードになっているファイルディスクリプタからread()にしようとすると、ファイルの偽の状態になります。

要約すると、ファイルストリームとストリームバッファーがどのように機能するかを読んで理解しておく必要があります。ファイル記述子が実際にどのように動作するか、ノンブロッキングモードがどのように機能するか、正しいロジックを理解するためには、使用する必要があります。あなたはstd::cinと非ブロックのルートを行くことを主張し、getline()場合

ああ、そして、あなたはgetline()が実際に標準入力から改行を読み込むためgetline()によって返された文字列が終了したかどうかを判断する簡単な方法を持っていない、またはそれになりますファイル条件の時期尚早の偽の終わりに達し、入力の行全体が実際に読み取られたわけではありません。

したがって、ノンブロッキングモードの場合、std::cinは、getline()の代わりにread()を使用する必要があります。

関連する問題