Guten Abend! :-)



  • Könnt ihr mir eine Funktion nennen, welche aus einem fstream (eingelesene txt in diesem Fall) sämtliche chars extrahiert und nicht nur jeden vierten?
    Denn das ist meine Vermutung, dass die Funktion get() genau das macht.
    Denn wenn ich mir mit

    std::cout << file.get() << std::endl;

    alle Ascii-Werte einzeln anzeigen lassen möchte, kommt nur jeder vierte heraus.

    Entweder liegt das wirklich an der get(), oder an cout, aber ich habe eigentlich get im Verdacht...

    Danke schon mal für die Antworten! 🙂

    JTR



  • Der Fehler liegt anderswo. Warum sollte es eine Standard-Funktion geben, die nur jedes vierte Zeichen ausliest?! Das wäre doch abwegig!

    Entweder liegt das wirklich an der get(), oder an cout, aber ich habe eigentlich get im Verdacht...

    Woher kommt der Verdacht?!



  • @wob
    Der rührt daher, weil ich sonst mit getline(file, word, ' ') jedes Wort wunderbar angezeigt bekomme.
    Da ist das halt.
    Allerdings ist da noch jedes Sonderzeichen, welches direkt am Wort ist (also bspw. "bspw.") auch mit drin, weswegen

    getline(file, wort, ' ')
    std::cout << wort;

    "bspw." und nicht nur "bspw" als Ausgabe hätte.



  • Wie gesagt, daran liegt es nicht. Der relevante Codeteil muss anderswo sein.

    #include <cctype>
    #include <fstream>
    #include <iostream>
    
    int main(){
      std::ifstream f("hier-deine-datei");
      int c;
      while ((c = f.get()) != EOF)
        std::cout << (std::isgraph(c) ? (char)c : ' ') << ": " << c << '\n';
    }
    


  • @wob Oder kann das an der txt liegen?



  • @JTR666 sagte in Guten Abend! 🙂:

    @wob Oder kann das an der txt liegen?

    Nein, es muss an deinem Programm liegen. Du machst etwas falsch.
    Zeige Code für ein reproduzierbares Beispiel, wo das passiert.



  • @JTR666
    Aber eigentlich auch nicht, denn mit getline(...) kann der Text wunderbar ausgespuckt werden...



  • @JTR666 sagte in Guten Abend! 🙂:

    @JTR666
    Aber eigentlich auch nicht, denn mit getline(...) kann der Text wunderbar ausgespuckt werden...

    Es bringt nichts, wenn du weiter keinen Code zeigst. Wenn ich aus dem Fenster schaue, sehe ich Schnee. Ist genauso relevant.



  • This post is deleted!


  • #include <iostream>
    #include <vector>
    #include <fstream>
    #include <string>
    
    int main()
    {
    std::string text, word;
    char letter, c;
    std::fstream file;
    std::vectorstd::string wordlist, final_wordlist;
    std::vector<int> counter;
    
    file.open("Der_verwirrte_Mann.txt");
    
    do
    {
        std::cout << (char)file.get() << std::endl;
        /*if(65 <= file.get() <= 90 || 97 <= file.get() <= 122)
        {
            word += file.get();
    
            if(0 <= file.get() < 65 || 91 <= file.get() < 97)
            {
                wordlist.push_back(word);
            }
        }
    
        word = ' ';*/
    }while(!file.eof());
    
    /*string_compare(wordlist, file, counter);*/
    
    /*for(int i=0; i<wordlist.size(); i++)
    {
        std::cout << wordlist[i] << " " << counter[i] << std::endl;
    }*/
    
    return 0;
    


  • @JTR666 sagte in Guten Abend! 🙂:

    /*if(65 <= file.get() <= 90 || 97 <= file.get() <= 122)

    Das Programm reproduziert den Fehler nicht, weil der fehlerhafte Teil auskommtiert ist.

    Hinweis: auch ein .get() innerhalb eines if liest ein Zeichen ein.
    Hinweis 2: Mehrfachverkettungen wie 1 < a < 3 gibt es nicht. Daraus wird 1 < a (was ein bool ist), dessem Wert also 0 oder 1, wird dann weiter verglichen.
    Hinweis 3: der EOF-Check muss direkt hinter das get(), nicht ans Ende. Siehe mein Beispiel.
    Hinweis 4: siehe https://en.cppreference.com/w/cpp/header/cctype und werde deine Zahlen wie 90, 65, ... los.



  • @wob Ich dachte halt die ganze Zeit, dass eof für "end of file" stünde, weswegen ich das n die while-Bedingung gepackt hab. 😃
    Was macht die Funktion get denn dann im Einzelnen?
    Also sie liest ja immer einen neuen char aus.
    Wenn dann eine if-Verknüpfung kommt, interpretiert sie diese ebenfalls als ein Zeichen, weil damit erst mal der filestream unterbrochen wird, oder wie?



  • @JTR666 sagte in Guten Abend! 🙂:

    Ich dachte halt die ganze Zeit, dass eof für "end of file" stünde,

    Und wie kommst du nun darauf, dass das nicht so ist?!



  • @JTR666 sagte in Guten Abend! 🙂:

    weil damit erst mal der filestream unterbrochen wird,

    Da wird nichts unterbrochen.



  • @JTR666 sagte in Guten Abend! 🙂:

    /* ... */
    

    ftfy

    #include <cctype>
    #include <string>
    #include <map>
    #include <algorithm>
    #include <fstream>
    #include <iostream>
    
    template<typename UnaryPredicate>
    void ltrim(std::string &str, UnaryPredicate p)
    {
        str.erase(str.begin(), std::find_if(str.begin(), str.end(), p));
    }
    
    template<typename UnaryPredicate>
    void rtrim(std::string &str, UnaryPredicate p)
    {
        str.erase(std::find_if(str.rbegin(), str.rend(), p).base(), str.end());
    }
    
    int main()
    {
        auto const filename = "foo.txt";
        std::ifstream is{ filename };
        if (!is.is_open()) {
            std::cerr << "Couldn't open \"" << filename << "\" for reading :(\n\n";
            return EXIT_FAILURE;
        }
    
        std::map<std::string, long long unsigned> words;
        for (std::string word; is >> word;) {
            ltrim(word, [](char unsigned ch) { return std::isalpha(ch); });
            rtrim(word, [](char unsigned ch) { return std::isalpha(ch); });
            std::transform(word.begin(), word.end(), word.begin(), std::tolower);
            ++words[word];
        }
    
        for (auto const& word : words)
            std::cout << '\"' << word.first << "\":\t" << word.second << '\n';
    }
    


  • @JTR666 sagte in Guten Abend! 🙂:

    Was macht die Funktion get denn dann im Einzelnen?
    Also sie liest ja immer einen neuen char aus.

    Ja. Genau. Jedes mal wenn Du std::basic_istream::get() aufrufst bekommst Du das jeweils nächste Zeichen oder EOF zurück - egal wo Du die funktion Aufrufst.

    Alleine hier (ich habe das /* entfernt)

    @JTR666 sagte in Guten Abend!:

        std::cout << (char)file.get() << std::endl;
        if(65 <= file.get() <= 90 || 97 <= file.get() <= 122)
        {
            word += file.get();
    
            if(0 <= file.get() < 65 || 91 <= file.get() < 97)
            {
                wordlist.push_back(word);
            }
        }
    

    liest Du also minimal 2, maximal 6 Zeichen. (Short-circuit evaluation).

    Du solltest auch Magic Numbers im Code vermeiden und stattdessen in diesem Fall die Funktionen aus <cctype> verwenden.

    Wenn man Zeichen will sollte man auch Character literals verwenden anstatt Integer. Also zB.

    bool is_upper(char ch)
    {
        return 'A' <= ch && ch <= 'Z';
    }
    

    und NICHT

    bool is_upper(char ch)
    {
        return 65 <= ch && ch <= 90;
    }
    

Log in to reply