iostream: Ist es moeglich nextline character anders als whitespace zu behandeln?



  • Hi,
    ich habe ein kleines Problem.
    Ich muss zuerst sagen, das ich wirklich nur sehr eingeschraenkt Erfahrung mit C++ Streams habe, von daher hoffe ich das jemanden hier vielleicht gleich eine einfache Loesung einfaellt.

    Ich habe das in einer Textdatei stehen.

    9 0 6 | 15 14 9
    5 | 8
    13 4 15 1 15 5 | 1 4 15 14 8 2

    Jede Line ist ein Testcase und in der Zeile befinden sich 2 Listen (getrennt mit '|' die ich miteinander multiplizieren muss.

    Ich kann leider kein C++11 einsetzen oder die <regex> Biblothek ansonsten haette ich getline() benutzt, den String bei '|' gesplittet und waere dann mit dem std::sregex_token_iterator ueber den String gerannt.

    e.g.:

    // um eine ungefaehre Idee zu bekommen.
    ifstream stream("text.txt");
    string line;
    std::vector<int>cont1;
    std::regex ws_re(" ");
    
    while (getline(stream, line))
    {
    //imagine string splitting
    std::sregex_token_iterator t(line.begin(), line.end(), ws_re, -1);
    for (t; t != std::sregex_token_iterator(); ++t)
         cont1.push_back(std::stoi(*t));
    }
    //etc
    

    Meine naechste Idee war.

    string line;
    vector<int> cont1;
    vector<int> cont2;
    bool inFirstList = true;
    while(stream >> line)
    {
    // handle delimiter('|' here
    if (inFirstList)
       cont1.emplace_back(std::stoi(line));
    else
       cont2.emplace_back(std::stoi(line));
    }
    

    Leider scheitert das daran, dass ich anscheinend nicht das nextline Zeichen intercepten kann und in jeder Line ein eigenstaendiger Testcase steht.
    Ich habe die Funktion std::skipws gefunden allerdings behandelt die whitespaces und nextline Zeichen gleich und ich will ja whitespaces skippen.

    Vielleicht faellt ja jemandem eine elegante Loesung fuer das Problem ein, ohne manuell durch den String zu rennen und zu parsen?


  • Mod

    https://www.c-plusplus.net/forum/p1940874#1940874

    Wenn du das Forum nach is_endl durchsuchst, findest du auch noch zahlreiche weitere Anwendungsbeispiele: Google: is_endl site:www.c-plusplus.net



  • Kannst du dich darauf verlassen, dass die Datei korrekt daherkommt?

    std::ifstream test("text.txt");
    
    	while (test)
    	{
    		int i;
    		std::string sep;
    		std::vector<int> cont1, cont2;
    
    		while (test >> i)
    			cont1.push_back(i);
    		test.clear();
    		test >> sep;
    
    		while (cont2.size() != cont1.size() && test >> i)
    			cont2.push_back(i);
    
    		assert(cont1.size() == cont2.size());
    	}
    


  • SeppJ schrieb:

    https://www.c-plusplus.net/forum/p1940874#1940874

    Wenn du das Forum nach is_endl durchsuchst, findest du auch noch zahlreiche weitere Anwendungsbeispiele: Google: is_endl site:www.c-plusplus.net

    OMG, meinst du etwa Werner Salomons Lösung zu dem Problem?
    is_endl.h (https://www.c-plusplus.net/forum/272390-full )

    Um ehrlich zu sein wollte ich nur Newline intercepten und nicht die Frage nachdem Sinn des Lebens lösen.

    Ich guck es mir auf jedenfall an.
    Ich habe auch keinen Zweifel daran, dass es funktionieren wird aber die Lösung sieht mir einfach verglichen mit der Art/Trivialität des Problems viel zu kompliziert aus.
    Auch von der Größe des Codes würde selber parsen aufs gleiche rauskommen und auch viel verständlicher sein.



  • Hallo Ruvi,

    auf Newline abzufragen ist in Deinem Fall gar nicht nötig, wie semitoll schon richtig erkannt hat. Du brauchst nur die Zahlen bis '|' zu lesen und anschließend die gleiche Anzahl der Zahlen noch einmal.
    Im Gegensatz zu semitoll würde ich nicht auf einen Fehler laufen sondern das nächste Zeichen direkt abfragen. Sieht in etwa so aus:

    #include <iostream>
    // #include <random>
    // #include <cmath>
    #include <fstream>
    #include <vector>
    
    int main() 
    {
        using namespace std;
        ifstream stream( "text.txt" );
        if( !stream.is_open() )
        {
            cerr << "Fehler beim Oeffnen" << endl;
            return -2;
        }
        for( ; stream; ) // über alle Testcases
        {
            vector< int > cont1;
            for( char c; stream >> c && c != '|'; ) // lese bis zum Pipe-Zeichen
            {
                int x;
                if( stream.putback( c ) >> x )
                    cont1.push_back( x );
            }
            vector< int > cont2;
            for( int x; cont2.size() < cont1.size() && stream >> x; ) // Fülle cont2, bis genauso viele Zahlen wie in cont1 enthalten sind
                cont2.push_back( x );
            if( !stream )
                break;      // Lesefehler bzw. Dateiende
                            // Dateiende liegt vor, wenn stream.eof() und cont1.empty() ==true sind
    
            // -- ab hier stehen 'cont1' und 'cont2' zur Verfügung
            // ...
            ;
        }
    
        return 0;
    }
    

    Ruvi schrieb:

    OMG, meinst du etwa Werner Salomons Lösung zu dem Problem? ... Auch von der Größe des Codes würde selber parsen aufs gleiche rauskommen und auch viel verständlicher sein.

    Der eigene Code ist immer verständlicher als der von anderen Leuten. Das geht mir genauso 😉
    Deshalb wird der gleiche Code ja auch immer wieder neu geschrieben.

    Gruß
    Werner



  • @suboptimal, Werner

    Ah, danke auf die Idee mit dem Counter bin ich nicht gekommen.



  • Werner mag Leerzeichen gerne, wa?

    Hatte anfangs auch immer so Leerzeichen gesetzt, mir es dann aber wieder abgewohnt, weil es irgendwie jeder doof fand.

    Aber wenn er das macht darf ich es auch!



  • Stil frage schrieb:

    Werner mag   Leer zeichen   gerne   ,   wa   ? 
    Hatte anfangs   auch immer   so Leer zeichen   gesetzt   ,   
    mir es dann aber    wieder abgewohnt   ,   weil es irgendwie   
     jeder      doof      fand.
    Aber wenn    er das    macht darf    ich es auch    !
    

    Klar, darfste.
    Ich beschränke mich lieber auf die wenigen, die für die Korrektheit notwenig sind.



  • volkard schrieb:

    Stil frage schrieb:

    Werner mag   Leer zeichen   gerne   ,   wa   ? 
    Hatte anfangs   auch immer   so Leer zeichen   gesetzt   ,   
    mir es dann aber    wieder abgewohnt   ,   weil es irgendwie   
     jeder      doof      fand.
    Aber wenn    er das    macht darf    ich es auch    !
    

    Klar, darfste.
    Ich beschränke mich lieber auf die wenigen, die für die Korrektheit notwenig sind.

    Ne,das...find ich auch nicht(so)schön!Eher ein(gesundes)Mittelmaß!

    Mal ehrlich, var = 4 + 5; ist schöner als var=4+5;



  • Stilfrage schrieb:

    Mal ehrlich, var = 4 + 5; ist schöner als var=4+5;

    Nö.
    Allein Deine eingestellte Schriftart ist viel zu klein.
    Und wer mehr als 80x25 braucht, hat einfach ein Übersichtsproblem.


  • Mod

    volkard schrieb:

    Doch



  • edit: Ganzen Beitrag weggemacht, Info per Mail ist besser.


  • Mod

    volkard schrieb:

    edit: Ganzen Beitrag weggemacht, Info per Mail ist besser.

    Ich nehme an, das war nicht an mich gerichtet? 😕


Log in to reply