Frage

Ich einfachen Code ich schreibe, die eine Reihe von Namen zu extrahieren, int Paare aus einer Datei. Ich Modifizieren bestehender Code, der gerade verwendet:

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

Aber ich mag eine andere (ähnliche) Eingabedatei verwenden, die die gleichen ersten beiden Spalten haben, werden aber durch andere Daten folgen (das ignoriert wird). Also schreibe ich:

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

Aber dies nicht zu kompilieren, ist die typische obszöne std lib Vorlage geben speien:

 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...]

Richtig. Linie ist kein std :: string, aber eine gewisse Variation von std :: basic_string usw. Allerdings instanziiert wird, explizit die string funktioniert.

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

Warum? Was ist los mit dem ersten Fall? Der Beispiel basic_io an dem immer hilfreich cplusplus.com funktioniert, funktioniert, warum nicht mein Code?

Update: Ein weiterer Bezugspunkt: der temporäre string funktioniert, wenn der erste Wert ein int anstelle einer Zeichenfolge extrahiert ist:

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

Lösung

Drei Gruppen von Elementfunktionen und eine Gruppe von globalen Funktionen Überlastung dieses „Eingabe-Operator“ (>>), finden Sie unter http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/ .

  • string (Linie); --created ein temporäres Objekt
  • string ss (Linie), -. Ein normales Objekt

, wenn „chrom“ int ist, Operator >> als arithmetischen Extraktor überlastet, die Mitgliederfunktionen sind. Sowohl das normale Objekt oder temporäres Objekt funktioniert.

Wenn „chrom“ string ist, Operator >> sollte als istream& operator>> (istream& is, char* str) überlastet werden, ist dies eine globale Funktionen, die den Objektverweis als Parameter übernehmen sollte. Angesichts der Tatsache temporäres Objekt, werden wir nicht temporäre Objekte durch nicht konstante Referenz in Standard C ++ durchgelassen. Die Überlastfunktion kann nicht die Referenz des temporären Objekts erhalten, wenn die Überlastfunktion als istream& operator>> (const istream& is, char* str) definiert ist. Leider ist das nicht die Tatsache. Die Funktion (en) kann nicht in dem temporären Objekt Fall überlastet werden und damit die Fehler wie error: no match for function... heraus geben

Andere Tipps

auf der Antwort von John Weldon zu erweitern, der extrace Operator ">>" macht zwei Dinge:

  1. Extrahiert den nächsten Wert und legt sie in die Variable auf der rechten Seite des Operators.
  2. erhöht die aktuelle Position des Stroms auf der linken Seite.

Daher ist es ändert seinen beiden linken und rechten Operanden. In Ihrem Fall ist der linke Operand einen temporären Wert, und die Compiler-runzelt die Stirn auf ihn zu ändern.

Einige Operatoren in C und C ++ erfordert, dass der Wert auf der linken Seite des Operators einen L-Wert sein, das heißt, dass sie geändert werden können.

Hier ist eine vollständigere Erklärung.

Da die erste aus dem string extrahiert Wert ist ein std :: string. Wenn es, sagen, ein int, würde die string (Linie) Version.

Es gibt keine Memberfunktion Operator >> in string für std :: string. Daher kann der vorübergehende Strom nicht als L-Wert funktionieren.

Nicht, dass ich voll und ganz die oben verstehen ... aber vielleicht ist es ein Ausgangspunkt für eine bessere Antwort.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top