Beim lesen aus datei, ließt er immer zuviel



  • Wenn in einer datei "Hallo" steht, ließt er "Hallo "!

    Wie kann ich das verhindern?

    Habe schon in FAQ gesucht, und Forensuche, habe nix gefunden!

    DAnke schonmal!



  • Hallo,
    zeig doch einfach mal den Code, der das Problem verursacht.





  • noch ne vermutung: du ließt mit while(!file.eof())
    da ließt er solange bis das dateiende überschritten ist (vorher weiß er ja nicht wann datei zu ende), dadurch 1 zeichen zuviel! (Glaub ich das es so ist...)



  • also der code sieht so aus! (ACHTUNG: ist nicht optimiert, einfach erstmal hingeklatscht)
    d.h. Extension habe ich fest im code geschrieben (*.txt)
    Dateinamen baue ich noch ziemlich kompliziert zusammen
    keine Fehlerbehandlung eingebaut

    aber die sachen werden noch geändert!

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    #include <iostream>
    #include <conio>
    #include <fstream>
    #include <string>
    using namespace std;
    
    //---------------------------------------------------------------------------
    
    #pragma argsused
    char coder(char text,int key)                         //CODER
    {
     return text+key;
    }
    
    char decoder(char text,int key)                       //DECODER
    {
     return text-key;
    }
    string delline(string filenstring)                    //PARAMETERSTRING bearbeiten
    {
     int pos=filenstring.find_first_of("-",0);
     string newstring = filenstring.erase(pos,1);
     return newstring;
    }
    
    int main(int argc, char* argv[])
    {
    cout<<"|-----------------------------------------|"<<endl;
    cout<<"|XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |"<<endl;
    cout<<"|XXXXXXXXXXXX                             |"<<endl;
    cout<<"|                                         |"<<endl;
    cout<<"|By XXXXXXXXXXXXXXXXXXX                   |"<<endl;
    cout<<"|©2005 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |"<<endl;
    cout<<"|-----------------------------------------|"<<endl;
    int param = argc;
    string sourcename;
    string method;
    string extsource=".txt";
    string dest="_code";
    string filenamesource,filenamedest;
    if((param<3)||(param>3))                        
     {
     cout<<"Falsche Parameterzahl oder Syntax"<<endl;
     cout<<"Programmname [-Urpsprungsdatei] [-Methode]"<<endl;
     }
    else
    {
     sourcename=delline(argv[1]);
     method=delline(argv[2]);
     filenamesource=sourcename+extsource;
     filenamedest=sourcename+dest+extsource;
     ifstream source(filenamesource.c_str());
     //cout<<filenamedest<<endl;
     ofstream dest(filenamedest.c_str());
     if(source)
     {
      while(!source.eof())            //lesen solange quelldatei nicht am ende
      {
       char ch;
       ch=source.get();
       if(method=="code")             //codieren
        dest.put(coder(ch,4));
       else if(method=="decode")      //decodieren
        dest.put(decoder(ch,4));
       else
        {
        cerr<<"Falsche Methode"<<endl;  //falsche methode
        dest.close();            
        source.close();
        }
      }
     }
     else
     cout<<"Datei nicht gefunden"<<endl;
     dest.close();
     source.close();
    }
     getch();
            return 0;
    }
    //---------------------------------------------------------------------------
    


  • Navigon schrieb:

    while(!source.eof())

    Das ist das Problem (wie 5er1als Kristallkugel schon vermutet hat).

    eof() liefert erst nach einem erfolglosen Lesen true.



  • ok, und wie behebe ich das?



  • Erst Zeichen einlesen, dann eof prüfen, dann verarbeiten.





  • ok, also auf failbit testen, aber wo?



  • Steht ganz genau im Link von Caipi.



  • jo hab ich, versteh das aber mit der for schleife nicht!



  • for (int i; (in >> i).fail() == false; )
    

    Ich denke mal du meinst das hier.
    Ist doch ganz einfach. Es wird solange ein Ineteger i eingelesen aus in bis das failbit gesetzt ist. Dann wird die Schleife abgebrochen.
    Das schöne ist, dass du die Lese- und Testoperation direkt im Schleifenkopf stehen hast.



  • aber ich will keine zahlen lesen!
    wahrscheinlich denk ich grad falsch?!



  • Hallo,
    du hast:

    while(!source.eof())            //lesen solange quelldatei nicht am ende 
    { 
       char ch; 
       ch=source.get(); 
       ...
    }
    

    Es gibt von eine Variante von get, die das gelesene Zeichen in einem Ausgabeparameter liefert und als Rückgabewert den Stream selbst hat.
    Damit kannst du deinen Code ganz einfach korrigieren:

    for (char ch; source.get(ch); )
    {
        ...
    }
    

    source.get(ch); ist in diesem Kontext äquivalent zu source.get(ch).fail() == false.
    Du testet hier also nach jedem Leseversuch ob das Lesen geklappt hat oder nicht.



  • also komplett die while schleife austauschen??



  • navigon schrieb:

    also komplett die while schleife austauschen??

    Du kannst natürlich auch die while-Schleife beibehalten:

    char ch;
    while(source.get(ch))
    {
    ...
    }
    

    Du kannst den Test auch expliziter machen:

    while(!source.eof())
    {
        char ch = source.get();
        if (source)
        {  // Zeichen nur verarbeiten, wenn Lesevorgang erfolgreich war
    
        }
    }
    


  • ..zunächst darauf achten, dass du dich nur struktur- bzw. typweise in der Datei bewegst (gerade bei char wg. Endekennung wichtig).
    Wenn das Ganze verarbeitet wird; ist die Endekennung natürlich auch relevant.

    Ich würde dann mit cin.getline arbeiten.


Anmelden zum Antworten