Text einlesen und aufsplitten (C/C++)



  • Hallo Leute,

    ich habe folgendes Problem: Ich möchte einen Text aus einer Textdatei in einen Vektor einlesen. Zeilenweise ist das soweit kein Problem, nun möchte ich diese aber in Wörter aufteilen (Trennzeichen quasi " ", ?, !, .). Die Funkton strtok funktioniert allerdings nur für Char-arrays. Hat jemand eine Idee, wie ich das am geschicktesten mit Vektoren mache?! Oder gibt es noch eine Alternative?

    Vielen Dank und Grüße
    brasco2k



  • Du könntest es elegant mit einem Whitespace-Facet machen:

    Inhalt der Datei:

    hallo?welt!
    schoenes wetter. oder?
    

    Quellcode:

    #include <iostream>
    #include <algorithm>
    #include <fstream>
    #include <iterator>
    #include <string>
    #include <vector>
    using namespace std;
    
    class whitespace_facet : public ctype<char>
    {
    	private:
    		mask table[table_size];
    	public:
    		whitespace_facet(const char* separator) : ctype<char>(table)
    		{
    			copy(classic_table(),classic_table()+table_size,table);
    			for(; *separator; ++separator)
    				table[*separator] |= space;
    		}
    };
    
    int main()
    {
    	ifstream file("test.txt");
    	vector<string> text;
    
    	file.imbue( locale(locale(),new whitespace_facet("?!.")) );
    	copy(istream_iterator<string>(file),istream_iterator<string>(),back_inserter(text)); // Und schon befindet sich jedes einzelne Wort separat im vector.
    
    	copy(begin(text),end(text),ostream_iterator<string>(cout,"\n")); // Testausgaben
    }
    

    Ausgabe:

    hallo
    welt
    schoenes
    wetter
    oder
    

    Falls du kein C++11 benutzt, ersetzt du begin(text) und end(text) durch text.begin() und text.end()



  • Gugelmoser schrieb:

    Du könntest es elegant mit einem Whitespace-Facet machen:

    Inhalt der Datei:

    hallo?welt!
    schoenes wetter. oder?
    

    Quellcode:

    #include <iostream>
    #include <algorithm>
    #include <fstream>
    #include <iterator>
    #include <string>
    #include <vector>
    using namespace std;
    
    class whitespace_facet : public ctype<char>
    {
    	private:
    		mask table[table_size];
    	public:
    		whitespace_facet(const char* separator) : ctype<char>(table)
    		{
    			copy(classic_table(),classic_table()+table_size,table);
    			for(; *separator; ++separator)
    				table[*separator] |= space;
    		}
    };
    
    int main()
    {
    	ifstream file("C:\\Users\\Mando Diao\\Desktop\\ff\\test.txt");
    	vector<string> text;
    
    	file.imbue( locale(locale(),new whitespace_facet("?!.")) );
    	copy(istream_iterator<string>(file),istream_iterator<string>(),back_inserter(text)); // Und schon befindet sich jedes einzelne Wort seperat im vector.
    
    	copy(begin(text),end(text),ostream_iterator<string>(cout,"\n")); // Testausgaben
    }
    

    Ausgabe:

    hallo
    welt
    schoenes
    wetter
    oder
    

    Falls du kein C++11 benutzt, ersetzt du begin(text) und end(text) durch text.begin() und text.end()

    Wieso benutzt du nicht gleich die Member-Methode?
    Und wieso so unnötig komplex? MAch doch einfach eine Schleife 🤡 :

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <iterator>
    #include <algorithm>
    
    int main()
    {
          using namespace std;
          ifstream stream("test.txt");
          vector<string> output(1);
    
          for(char c(stream.get());stream.good();stream.get(c))
          {
                if(string("?.! \n").find(c) != string::npos)
                {
                      if(!output.back().empty())
                            output.push_back(string());
                      continue;
                }
    
                output.back() += c;
          }
    
          copy(output.begin(), output.end(), ostream_iterator<string>(cout, "\n")); // Same Story
    }
    


  • Hacker schrieb:

    Wieso benutzt du nicht gleich die Member-Methode?

    Was meinst du? Den Konstruktor von std::vector statt des copy-Befehls?

    Hacker schrieb:

    Und wieso so unnötig komplex?]

    Du nennst es unnötig komplex, ich nenne es elegant. 🙂



  • Gugelmoser schrieb:

    Hacker schrieb:

    Wieso benutzt du nicht gleich die Member-Methode?

    Was meinst du? Den Konstruktor von std::vector statt des copy-Befehls?

    Quatsch, bei std::copy einfach text.begin() anstatt begin(text) ...

    Gugelmoser schrieb:

    Hacker schrieb:

    Und wieso so unnötig komplex?]

    Du nennst es unnötig komplex, ich nenne es elegant. 🙂

    Da hast du Recht. Es war auch nur ein Spaß. Mir geht es halt darum, so wenig Text wie möglich zu haben - frag nicht warum... 😃


Anmelden zum Antworten