Datei auslesen mit Inserter


  • Mod

    Du brauchst back_inserter, copy und istream_iterator, dann kannst du damit einen Einzeiler schreiben. Die genaue Form lasse ich dir erst einmal zur Übung, die Beispiele zu den Links zeigen schon fast alles was du brauchst, du musst es nur noch richtig kombinieren.

    edit: Zu spät. Siehe Pis Zeile 3.



  • es geht auch ohne back_inserter ..

    std::ifstream is( "foo.txt" );
        std::vector<int> v( (std::istream_iterator< int >( is )), std::istream_iterator< int >() );
    

    Bem.: die extra-Klammer um den ersten Parameter ist bei einigen Compilern notwendig.

    Gruß
    Werner



  • Werner Salomon schrieb:

    Bem.: die extra-Klammer um den ersten Parameter ist bei einigen Compilern notwendig.

    Schreib doch gleich MSVC hin. Ein weiterer Punkt für mich.



  • Danke für den Hinweis auf istream_iterator.

    Mit int klappt es auch, aber bei z.B. pair<int, string> gibt es einen Compile-Fehler.

    #include <stdafx.h>
    #include <string>
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <algorithm>
    #include <regex>
    #include <iterator>
    
    using namespace std;
    
    istream& operator>>(istream& is, pair<int, string>& obj)
    {
    	string line;
    	getline(is, line);
    	cmatch matches;
    	regex rex("(\\d+)\\|(\\w+)");
    	regex_search(line.c_str(), matches, rex);
    	obj.first = strtol(matches[1].str().c_str(), 0, 0);
    	obj.second = matches[2];
    	return is;
    }
    
    int main()
    {
    	const char* filename = "test.txt";
    	ifstream file(filename);
    	istream_iterator< pair<string, int> > str_iter(file);
    	istream_iterator< pair<string, int> > end_iter;
    	vector< pair<int, string> > vec(str_iter, end_iter);
    	file.close();
    
    	for (vector< pair<int, string> >::iterator iter = vec.begin(); iter != vec.end(); ++iter)
    	{
    		cout << iter->first << ' ' << iter->second << '\n';
    	}
    	return 0;
    }
    

    error C2678: Binärer Operator '>>': Es konnte kein Operator gefunden werden, der einen linksseitigen Operanden vom Typ 'std::basic_istream<_Elem,_Traits>' akzeptiert (oder keine geeignete Konvertierung möglich)



  • Das hängt mit dem Lookup zusammen. Der Compiler sucht nur im Namensraum std nach dem Operator, dort wird er ihn nicht finden.

    Zwei Möglichkeiten:

    • Du fügst deinen Operator zu std hinzu (nicht schön!)
    • Du wrappst einfach dein std::pair<int, string> in eine eigene struct MyPair

    Hier sollte dann ADL auch funktionieren.

    BTW:

    Wurstinator schrieb:

    istream_iterator< pair<string, int> > str_iter(file);
    istream_iterator< pair<string, int> > end_iter;
    vector< pair<int, string> > vec(str_iter, end_iter);
    

    Typen vertauscht 😉



  • Den operator zu std hinzuzufügen klappt leider auch nicht:

    #include <stdafx.h>
    #include <string>
    #include <iostream>
    #include <fstream>
    #include <vector>
    #include <algorithm>
    #include <regex>
    #include <iterator>
    
    using namespace std;
    
    namespace std
    {
    istream& operator>>(istream& is, pair<int, string>& obj)
    {
    	string line;
    	getline(is, line);
    	cmatch matches;
    	regex rex("(\\d+)\\|(\\w+)");
    	regex_search(line.c_str(), matches, rex);
    	obj.first = strtol(matches[1].str().c_str(), 0, 0);
    	obj.second = matches[2];
    	return is;
    }
    }
    
    int main()
    {
    	const char* filename = "test.txt";
    	ifstream file(filename);
    	istream_iterator< pair<string, int> > str_iter(file);
    	istream_iterator< pair<string, int> > end_iter();
    	vector< pair<string, int> > vec;//(str_iter, end_iter);
    	file.close();
    
    	for (vector< pair<string, int> >::iterator iter = vec.begin(); iter != vec.end(); ++iter)
    	{
    		cout << iter->first << ' ' << iter->second << '\n';
    	}
    	return 0;
    }
    

    Oder habe ich dich da falsch verstanden?

    Typen vertauscht 😉

    Ups 🙂



  • Aquae schrieb:

    Du fügst deinen Operator zu std hinzu (nicht schön!)

    nicht erlaubt!



  • @Wurstinator: Schau dir mal Signatur deines operator>> an, insbesondere die Typen-Reihenfolge von pair 😉



  • Aquae schrieb:

    @Wurstinator: Schau dir mal Signatur deines operator>> an, insbesondere die Typen-Reihenfolge von pair 😉

    Ich vermisse einen Head-Desk-Smiley 😃
    Danke. Bei der Fehlersuche habe ich die beiden Typen getauscht, aber wohl nicht überall daran gedacht.


  • Mod

    Wurstinator schrieb:

    Ich vermisse einen Head-Desk-Smiley 😃
    Danke. Bei der Fehlersuche habe ich die beiden Typen getauscht, aber wohl nicht überall daran gedacht.

    😕 Ich dachte, das hättest du mit

    Wurstinator schrieb:

    Typen vertauscht 😉

    Ups 🙂

    schon gemeint. Sonst hatte ich dir das nämlich auch schon vor einer Stunde sagen können. 🙂


Anmelden zum Antworten