Frage zu fstream/ifstream methode get()



  • Hallo, Ich hab schon wieder ein Problem:

    Im folgenden Code funktioniert die get() Methode nur, wenn ich nicht als Test die aktuelle Position ausgebe.

    Die Funktion liest(in dieser Form, soll anders ausehen, nur hab cih den Rest derzeit auskommentiert) einfach den Inhalt einer Textdatei(test.txt von myfile geöffnet und per win editor von mir erstellt) und gibt ihn aus.

    streampos find(ifstream& myfile,string word,const char ignore)
    {
        char c;
        if(myfile.good())
        cout << "test"<< endl;
        while(!myfile.eof())
        {
            myfile.get(c);
    //cout << "\n"<<myfile.tellg()<<endl; <- wird dies hinzugefügt, geht nichts mehr
            cout << c;
    
        }
    
    }
    

    Füge ich nun das "myfile.tellg()" hinzu(siehe code) überspringt der stream plötzlich mehrere Zeichen.(D.h. get() liefert nicht das nächste Zeichen sondern in meinem Fall das 3. nächste bzw. übernächste(ändert sich zwischendrin)).
    Das Verhalten kann ich mir absolut nicht erklären. tellg() ändert ja die Position des getzeigers nicht(auch schon getestet ;)) und sonst ist ja nichts drin. Get() soll zudem nur ein einzelnes Zeichen auslesen und in c speichern, also kann es daran auch nicht liegen 😕
    Wo liegt diesmal mein Fehler?
    Vielen Dank für eure Antworten.
    edit: man ignoriere, dass hier was returned werden müsste


  • Mod

    Bis auf die falsche Abbruchbedingung (was passiert mit dem Zeichen, das EOF ausgelöst hat?) hast du keinen offensichtlichen Fehler. Versuch einmal ein minimales compilierbares Beispiel zu erstellen, damit wir deinen Code ausprobieren können.



  • Ok, danke, das mit der Abbruchbedingung ist mir bekannt.
    Hier mal als stand-alone Projekt(Konsole)

    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        ofstream myfileoutput("test.txt");
        myfileoutput << "[Command]\nname = \"abc\"\n";
        myfileoutput.close();
        ifstream myfileinput("test.txt");
    
        char c;
        if(myfileinput.good())
        cout << "test"<< endl;
        while(!myfileinput.eof())
        {
            myfileinput.get(c);
    cout << "\n"<<myfileinput.tellg()<<endl; 
            cout << c;
    
        } 
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    

    exakt der gleiche Fehler.
    Ohne den "cout << myfileinput.tellg() blabla" gibt er die Datei komplett aus, mit gehts nicht.


  • Mod

    Leider funktioniert das bei mir 1a so wie es soll, ich kann den Fehler daher nicht nachvollziehen 😞 :

    test
    
    1
    [
    2
    C
    3
    o
    4
    m
    5
    m
    6
    a
    7
    n
    8
    d
    9
    ]
    10
    
    11
    n
    12
    a
    13
    m
    14
    e
    15
    
    16
    =
    17
    
    18
    "
    19
    a
    20
    b
    21
    c
    22
    "
    23
    
    -1
    

    Was gibt es denn bei dir aus?



  • http://up.picr.de/4247633.jpg

    das hier.
    Ist ja sehr seltsam?!


  • Administrator

    SeppJ schrieb:

    Leider funktioniert das bei mir 1a so wie es soll, ich kann den Fehler daher nicht nachvollziehen 😞 :

    Welchen Kompiler verwendest du? Ich kann ihn nämlich nachvollziehen und denke, dass ich auch weiss wieso 🙂

    Problem ist, dass ohne die Angabe von std::ios::binary beim Öffnen des Files, der Stream die Möglichkeit hat, die Eingabe (oder Ausgabe) zu verändern. Beim MSVC wird zum Beispiel beim Schreiben aus einem "\n" ein "\r\n" . Beim Einlesen wird der umgekehrte Falle durchgeführt, also aus einem "\r\n" wird ein "\n" gemacht. Im File ist der Stream aber tatsächlich 2 Schritte vorwärts gegangen, weshalb tellg dies auch mitteilt. Dem ganzen kann man mit std::ios::binary entgegenwirken, so ist dem Stream verboten, irgendetwas an den Eingaben/Ausgaben zu verändern und es wird 1:1 gelesen/geschrieben.

    Edit: Ok, ganz so schlimm wie bei kingcools ist es bei mir auch nicht. Bei mir trat der Fehler bei einem Linefeed auf. Aber der Fehler von kingcools könnte auch daran liegen:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-237002.html

    Grüssli



  • Ich selber benutze wxDev-C++.
    Wenn die Umwandlung der Zeichen(also z.B. \n -> \r\n) in beide Richtungen geschieht, wäre es ja egal. Aber ich glaueb nicht, dass das hier das Problem ist, da er mitten in normalen Zeichenketten springt.
    Aber danke für den Tipp 🙂



  • Dravere schrieb:

    SeppJ schrieb:

    Leider funktioniert das bei mir 1a so wie es soll, ich kann den Fehler daher nicht nachvollziehen 😞 :

    Welchen Kompiler verwendest du? Ich kann ihn nämlich nachvollziehen und denke, dass ich auch weiss wieso 🙂

    Problem ist, dass ohne die Angabe von std::ios::binary beim Öffnen des Files, der Stream die Möglichkeit hat, die Eingabe (oder Ausgabe) zu verändern. Beim MSVC wird zum Beispiel beim Schreiben aus einem "\n" ein "\r\n" . Beim Einlesen wird der umgekehrte Falle durchgeführt, also aus einem "\r\n" wird ein "\n" gemacht. Im File ist der Stream aber tatsächlich 2 Schritte vorwärts gegangen, weshalb tellg dies auch mitteilt. Dem ganzen kann man mit std::ios::binary entgegenwirken, so ist dem Stream verboten, irgendetwas an den Eingaben/Ausgaben zu verändern und es wird 1:1 gelesen/geschrieben.

    Edit: Ok, ganz so schlimm wie beim TO ist es bei mir auch nicht. Bei mir trat der Fehler bei einem Linefeed auf. Aber der Fehler beim TO könnte auch daran liegen:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-237002.html

    Grüssli

    1. Das mit dem ios::binary wird ja wohl nicht auf ganz normale Buchstaben anspielen, sondern wie du gesagt hast, auf \r\n.
    2. Wäre es \r\n, könnte es ja sein, dass SeppJ kein Windows nutzt.
    3. Seit wann benutzt fstream UTF-24 😃


  • Mod

    Hoppla, Doppelpost.


  • Mod

    Dravere schrieb:

    SeppJ schrieb:

    Leider funktioniert das bei mir 1a so wie es soll, ich kann den Fehler daher nicht nachvollziehen 😞 :

    Welchen Kompiler verwendest du? Ich kann ihn nämlich nachvollziehen und denke, dass ich auch weiss wieso 🙂

    Das funktionierende Programm ist mit dem gcc 4.4.1 compiliert und wie wxSkip richtig anmerkt, sollte ich wohl noch erwähnen, dass bei meiner Konsole der Zeilenumbruch \n und nicht \r\n ist.

    P.S.: Gerade getestet: Der Intelcompiler 11 macht auf der gleichen Konsole das gleiche wie der gcc.



  • SeppJ schrieb:

    Hoppla, Doppelpost.

    Seit wann darf man das denn? Oo
    Bei mir kommt so schon total oft: "du musst länger warten, um den nächsten Beitrag verfassen zu dürfen" oder irgendwie so was -.-


  • Administrator

    wxSkip schrieb:

    1. Das mit dem ios::binary wird ja wohl nicht auf ganz normale Buchstaben anspielen, sondern wie du gesagt hast, auf \r\n.

    Der Standard ist nicht sehr genau, was ohne std::ios::binary passiert. Ich kann jedenfalls nicht wirklich viel dazu finden, es ist einfach eine Umschaltung aus Textmodus zu Binärmodus. In gängiger Literatur wird davon gesprochen, dass dadurch plattformspezifische Anpassung vorgenommen werden können.

    Übrigens, ich habe gerade noch einen weiteren Test mit dem g++ 4.4.0 von TDM gemacht. Das Ergebnis sieht genau wie bei kingscool aus 😮
    Und wenn ich std::ios::binary angebe, dann wird alles richtig ausgegeben ... ehm, tja ... 😕 ... Der Standard ist halt eben nicht sehr genau in diesem Punkt 😃

    Grüssli


  • Mod

    unskilled schrieb:

    SeppJ schrieb:

    Hoppla, Doppelpost.

    Seit wann darf man das denn? Oo
    Bei mir kommt so schon total oft: "du musst länger warten, um den nächsten Beitrag verfassen zu dürfen" oder irgendwie so was -.-

    Das habe ich in letzter Zeit ganz oft. Ich klicke auf absenden und dann kommt sofort, dass ich nicht so schnell nacheinander Nachrichten abschicken kann. Aber wenn ich dann nachgucke, wurde der Beitrag zweimal gesendet. Sieht man ja an der Uhrzeit.

    Womöglich ein Fehler der Forensoftware der sich durch meine zittrige Maustaste offenbart.



  • Also ihr meint dass sei Compilerspezifisch? Seltsam, wäre halt bequemer, wenns auch ohne binary ging(da müsste ich die binaryspezifika die bei der Textverarbeitung auftreten nicht berücksichtigen)

    edit: Zumal ich mir das nicht als "feature" vorstellen kann, da ja mal nur ein Element übersüprungen wird und manchmal 2 UND jedesmal gcount() 1 ausgibt.


Anmelden zum Antworten