2017-01-08 19 views
1

各行にコロンで区切られた2つの文字列を含むテキストファイルがあります。C++ Stringstreamのみ最初の文字列を取得する

私は、getlineを使用して行全体を取得し、文字列ストリームを2つの文字列に分割してベクトルに配置します。このコードは、最初のパスで文字列を完全に取得するときに正常に機能します。その後、whileループの2回目のパスなどでは、新しい入力を取得しません。文字列ストリームは何らかの理由で元の最初の値を残しているようです。

if (infile.is_open()) { 
    std::stringstream ss; 
    std::string current_line; 
    std::string tempProxy; 
    std::string tempPort; 

    while (std::getline(infile, current_line)) { 
     ss << current_line; 
     std::getline(ss, tempProxy, ':'); 
     std::getline(ss, tempPort); 
     std::cout << tempProxy << " and " << tempPort << std::endl; 
    } 

なぜ最初の繰り返し以外のどのパスでも、current_lineの文字列を取得したくないのでしょうか?

+0

なぜ外側のスコープに 'ss'、' tempProxy'と 'tempPort'がありますか?なぜ 'ss'は' current_line'から単純に構築された 'std :: istringstream'ではないのですか? – LogicStuff

+0

それは奇妙なことですが、私はループの外で一度stringstreamを構築し、それを新しいストリームに供給するために>>演算子を使用すると、ループを通過するたびにそれを構築するより効率的であると考えました。 – mocode9

答えて

2

。最初の行から2番目の単語を抽出すると、ストリームが使い果たされ、 'EOF'状態になります。ストリームがこのまたは他の「エラー」状態にあるときは、何もしません。エラーをクリアしてから使用を続ける必要があります。

あなたがループ内でoperator<<getlineによって返されたエラーをチェックした場合(またはあなたがエラーの例外をスローするssを引き起こすした場合*)あなたは、彼らが最初の反復過去の成功していないことを示すされて見つけるだろう。常にエラーをチェックするのは良い一般的な方法です。特にデバッグしているときはそうです。

あなたのループを変更することでエラーをクリアすることができます

while (std::getline(infile, current_line)) { 
    ss.clear(); // clears the error, not the contents 
    ss << current_line; 

は、しかし、これを行うことはssは、その内部バッファ内のすべての行を蓄積することを意味します。ファイルが大きく、メモリが不足している場合やそうでない場合を除き、コードは期待される出力を生成します。あなたは、次のと蓄積内部バッファを見ることができます

:あなたはおそらく、以前のデータに置き換えられますされ、それを設定する.str()部材を用いたほうが良いでしょう代わりにssを追加するためにフォーマットされた入力を使用しての

while (std::getline(infile, current_line)) { 
    ss.clear(); 
    ss << current_line; 
    std::cout << "ss internal buffer: " << ss.str(); 

それに追加する代わりに。

while (std::getline(infile, current_line)) { 
    ss.clear(); 
    ss.str(current_line); 

また、ループの各繰り返しで新しいstringstreamを構築することもできます。これにより、以前の反復からエラー状態やデータが引き継がれることはありません。それはまた遅いかもしれませんが、あなた自身のためにプロファイルする必要があります。

while (std::getline(infile, current_line)) { 
    std::stringstream ss(current_line); 

*例外あなたがそれらをチェックするために覚えておく必要はありませんので、それらはデフォルトでは有効になっていない。このような場合を除いて...いいです。また、私はいくつかのC++の実装が、iostreamの例外コードにバグを持っていることに気付きました。

0

私はあなたのような何かを探していると思う:あなたはssを再利用するが、それを正しくリセットしていない

if (infile.is_open()) { 
    std::stringstream ss; 
    std::string current_line; 
    std::string tempProxy; 
    std::string tempPort; 

    while (std::getline(infile, current_line)) { 
     std::stringstream to_split; 
     to_split.str(current_line); 
     std::getline(to_split, tempProxy, ':'); 
     std::getline(to_split, tempPort); 
     std::cout << tempProxy << " and " << tempPort << std::endl; 
    } 
+0

それは奇妙です、私はループの外で一度stringstreamを構築し、それを新しいストリームを供給するために>>演算子を使用すると、ループを通過するたびにそれを構築するより効率的だと思った。しかし、それはあなたの方法ではなく、私のほうに働くようです。 – mocode9

関連する問題