[gelöst] Mit Stream-Extraction Operatoren lesen und gleichzeitig End-Of-Line mitbekommen?



  • Sollte mMn. eigentlich eine ganz einfache Sache sein, ich weiss aber keine einfache, gute Lösung.
    Angenommen wir haben ein File wo Zeilen mit "Zahlenwürsten" drinnen stehen:

    8 2 1 92 100 2
    1 2
    99 100 33 2 1 0 0 0 4
    ...
    

    Dieses File soll mittels C++ iostreams eingelesen werden.
    Das lesende Programm muss dabei allerdings die Zeilenumbrüche mitbekommen.

    Wie macht man das am elegantesten?

    Einfache (aber sehr ineffiziente und IMO nicht sehr elegante) Variante: getline() verwenden um die Zeilen in einen std::string zu lesen, dann einen std::stringstream daraus machen und über diesen dann die einzelnen Integers lesen.

    Ich meine aber dass das irgendwie besser gehen müsste.



  • Vielleicht so:

    #include <iostream>
    #include <fstream>
    
    int main(){
        std::ifstream stream("yowassup");
        int integer;
        char next;
    
        while(stream.get(next)){
            if(next == '\n')
                std::cout << "newline! :0\n";
            else{
                stream >> integer;
                std::cout << integer << ' ';
            }
        }
    
        return 0;
    }
    


  • Was hällst du davon?

    int main()
    {
    	ifstream file( "test.txt" );
    	vector<unsigned> numbers;
    	unsigned line_breaks = 0;
    
    	for(unsigned i;;)
    	{
    		file >> std::noskipws >> i;
    
    		if( !file )
    		{
    			if( file.eof() )
    				break;
    
    			file.clear();
    			char tmp;
    			file >> tmp;
    			if( tmp=='\n' || tmp=='\r' )
    				++line_breaks;
    		}
    		else
    		{
    			numbers.push_back( i );
    		}
    	}
    }
    


  • Ich korrigiere mich:

    #include <iostream>
    #include <fstream>
    
    int main(){
        std::ifstream stream("file");
        int integer, x;
        char next;
    
        while(stream.get(next)){
            if(next == '\n')
                std::cout << "newline! :0\n";
            else{
                x = stream.tellg();
                stream.seekg(--x, std::ios::beg);
    
                stream >> integer;
                std::cout << integer << ' ';
            }
        }
    
        return 0;
    }
    


  • Hallo hustbaer,

    hustbaer schrieb:

    Dieses File soll mittels C++ iostreams eingelesen werden.
    Das lesende Programm muss dabei allerdings die Zeilenumbrüche mitbekommen.

    Du bist wahrlich nicht der erste, der dieses Problem hat. Zeilenumbrüche und Leerzeichen sind halt beides White Space Character und werden vom std::istream nicht so ohne weiteres unterschieden.

    Ich hatte mal ein kleines Helferlein 'is_endl' gebaut - damit geht es dann relativ straightforward:

    #include "is_endl.h" // s. <http://www.c-plusplus.net/forum/p1940874>
    #include <iostream>
    #include <fstream>
    #include <vector>
    
    int main()
    {
        using namespace std;
        ifstream in("input.txt");
        if( !in.is_open() )
        {
            cerr << "Fehler beim Oeffnen der Datei" << endl;
            return -2;
        }
        vector< vector< int > > alles;
        while( in )
        {
            vector< int > zahlenwurst;
            for( int zahl; !is_endl(in) && in >> zahl; )
                zahlenwurst.push_back( zahl );
            if( in || !zahlenwurst.empty()  )
                alles.push_back( zahlenwurst );
        }
        cout << alles.size() << " Zahlenwuerste gelesen" << endl;
        return 0;
    }
    

    die anderen gemachten Vorschläge funktionieren nicht, wenn hinter der letzten Zahl einer Zeile noch ein Leerzeichen steht oder wenn Leerzeilen vorkommen.

    Gruß
    Werner



  • Werner Salomon schrieb:

    Hallo hustbaer,

    hustbaer schrieb:

    Dieses File soll mittels C++ iostreams eingelesen werden.
    Das lesende Programm muss dabei allerdings die Zeilenumbrüche mitbekommen.

    Du bist wahrlich nicht der erste, der dieses Problem hat. Zeilenumbrüche und Leerzeichen sind halt beides White Space Character und werden vom std::istream nicht so ohne weiteres unterschieden.

    Ja, gerade weil ich ganz sicher nicht der erste bin der das braucht hat es mich auch so gewundert dass es keine straight-forward Lösung dafür zu geben scheint.
    Ausser eben die getline() + stringstream Variante.

    Ich hatte mal ein kleines Helferlein 'is_endl' gebaut - damit geht es dann relativ straightforward:

    Dankeeeeeeee! 🙂


Log in to reply