3

私はファイルから名前とintのペアの束を抽出する簡単なコードを書いています。以下を使用する既存のコードを変更しています。

string chrom;
unsigned int size;
while ( cin >> chrom >> size ) {
    //  save values
}

しかし、最初の2つの列が同じで、その後に他のデータが続く(無視される)別の(類似した)入力ファイルを使用したいと思います。だから私は書く:

string chrom;
unsigned int size;
string line;
while ( getline(cin, line) ) {
    if( stringstream(line) >> chrom >> size ) {
        // save values
    }
}

しかし、これはコンパイルに失敗し、典型的なわいせつなstdlibテンプレートを吐き出します。

 error: no match for "operator>>" in "std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >(((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)((const std::basic_string<char, std::char_traits<char>, std::allocator<char> >*)(& line))), std::operator|(_S_out, _S_in)) >> chrom"
istream:131: note: candidates are: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>& (*)(std::basic_istream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
[...another dozen lines...]

右。lineはstd::stringではありませんが、std :: basic_stringなどのバリエーションです。ただし、stringstreamの明示的なインスタンス化は機能します。

string chrom;
unsigned int size;
string line;
while ( getline(genome, line) ) {
    stringstream ss(line);
    if ( ss >> chrom >> size ) {
       // save values
    }
    // Discard remainder of line
}

なんで?最初のケースの何が問題になっていますか?常に役立つcplusplus.comのサンプルbasic_ioが機能しますが、なぜ私のコードが機能しないのですか?

更新:別の参照ポイント:一時的な文字列ストリームは、抽出された最初の値が文字列ではなくintである場合に機能します。

unsigned int chrom;  // works as int...
unsigned int size;
string line;
while ( getline(cin, line) ) {
    if( stringstream(line) >> chrom >> size ) {
        // save values
    }
}
4

4 に答える 4

2

CおよびC++の一部の演算子では、演算子の左側の値が左辺値である必要があります。つまり、変更可能である必要があります。

これがより完全な説明です。

于 2009-11-30T23:22:23.860 に答える
2

John Weldonの答えを拡張するために、extrace演算子「>>」は2つのことを行います。

  1. 次の値を抽出し、演算子の右側の変数に配置します。
  2. 左側のストリームの現在の位置をインクリメントします。

したがって、左と右の両方のオペランドを変更します。あなたの場合、左側のオペランドは一時的な値であり、コンパイラーはそれを変更することに憤慨します。

于 2009-11-30T23:50:47.687 に答える
2

メンバー関数の 3 つのグループとグローバル関数の 1 つのグループは、この「抽出演算子」(>>) をオーバーロードします。 http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/を参照してください。

  • stringstream(行); -- 一時オブジェクトを作成しました
  • stringstream ss(line);-- 通常のオブジェクト。

"chrom" が int の場合、演算子 >> はメンバー関数である算術エクストラクタとしてオーバーロードされます。通常のオブジェクトまたは一時オブジェクトの両方が正常に機能します。

「chrom」が文字列の場合、演算子 >> は としてオーバーロードするistream& operator>> (istream& is, char* str)必要があります。これは、オブジェクト参照をパラメーターとして受け取るグローバル関数です。ただし、一時オブジェクトが与えられた場合、標準 C++ では非 const 参照によって一時オブジェクトを渡すことは許可されていません。オーバーロード関数が として定義されていない限り、オーバーロード関数は一時オブジェクトの参照を取得できませんistream& operator>> (const istream& is, char* str)。残念ながら、それは事実ではありません。一時オブジェクトの場合、関数をオーバーロードできないため、次のようなエラーが発生しますerror: no match for function...

于 2013-02-12T16:51:10.197 に答える
1

stringstream から抽出された最初の値は std::string であるためです。たとえば、int の場合、stringstream(line) バージョンが機能します。

std::string の stringstream にはメンバー関数 operator>> はありません。したがって、一時ストリームは左辺値として機能できません。

上記を完全に理解しているわけではありません...しかし、おそらくそれはより良い答えの出発点です。

于 2009-11-30T23:25:14.027 に答える