failbit bei fstream/schleife verhindern



  • chris01349 schrieb:

    ich teste einen ifstream auf failbit und badbit

    Nicht im gezeigten Code.

    Meine Frage war nun wie löse ich es ohne das das failbit in der schleife ausgelöst wird, da ich das failbit nur auslösen möchte bei falschem dateinamen z.B.

    Warum?



  • chris01349 schrieb:

    aber sofort beim ende der datei tritt natürlich catch ein.

    Welches catch? Nichts im gezeigten Code läßt einen Exceptions erwarten.



  • std::string file::read(std::string title) {
     std::ifstream in;
     char x; std::string data;
     int length = this->length(title);
    
     try {
      in.exceptions(std::ios::badbit|std::ios::failbit);       in.open(title.c_str(),std::ios::binary|std::ios::in);
      while(in.tellg() != length) { 
      in.get(x);
      data += x;
       } 
      in.close();
     }
    
     catch(std::ios::failure&) {
     if(in.bad()) { return("0"); } 
     if(in.fail()) { return("0"); } }
     return(data);
    }
    

    //length() gibt die zeichenlänge zurück

    So sieht der eigentlich code aus. Wenn ich jetzt aber am Ende der Schleife bin tritt natürlich in.fail() auf und der Dateninhalt wird mir nicht zurückgegeben. So wird aber glaub ich auch auf den falschen dateinamen geprüft. So wie der Code jetzt ist konnte ich es lösen, aber gibt es eine elegantere methode?

    Und ich habe eine methode check() die genau auf den dateinamen prüft. Möchte es aber nicht so viel verschachteln



  • Ich könnte natürlich failbit komplett herausnehmen, was ich aber vermeiden möchte



  • chris01349 schrieb:

    Ich könnte natürlich failbit komplett herausnehmen, was ich aber vermeiden möchte

    Warum? Du hast doch innen schon das while. Machst außen das if und brauchst .exceptions() nicht mehr, oder?



  • Nochmal leute wenn die schleife zu ende ist löst das eofbit automatisch das failbit aus, obwohl das gar nicht gesetzt ist... lass ich das failbit weg prüft dieses bit nicht mehr ob die datei vorhanden ist... ich kann damit leben aber ist das richtig so? oder was kann man da machen?



  • mein neuer code:

    bool file::copy(std::string input,std::string output) {
     std::ifstream in; std::ofstream out;
    
     try {
      in.exceptions(std::ios::badbit|std::ios::failbit);
      out.exceptions(std::ios::badbit|std::ios::failbit);
      in.open(input.c_str(),std::ios::binary|std::ios::in);
      out.open(output.c_str(),std::ios::binary|std::ios::out);
      char x; while(in.get(x)) { out.put(x); }
      in.close(); out.close();
     }
    
     catch(std::ios::failure&) {
      if(in.bad())   { return 0; }
      if(in.fail())  { return 0; }
      if(out.bad())  { return 0; }
      if(out.fail()) { return 0; }
     } return 1;
    
    }
    

    probiert es einfach mal selbst aus... und lasst dann mal das failbit von in. weg dann funktionierts

    ich weiß unschön vom stil...



  • Ich sehe nicht, warum du Exceptions wirfst bei eofbit, failbit oder
    badbit. Die unterschiedlichen Bit Masken sind doch dazu da um unterschiedliche Zustände zu händeln. Wenn du die alle gleich behandelst wirfst du den Vorteil weg.

    ifstream in(name);
    std::string data;
    if (in.is_open()){
      char x;
      while(in.get(x)) //iteriert bis EOF
        data += x; 
    }
    else{
    ...
    }
    

    //Edit: Natürlich kannst du nach der while Schleife den Zustand deines Streams überprüfen um zu testen weshalb das Lesen abgebrochen wurde, falls das für dich interessant ist.



  • bool file::copy(std::string input,std::string output) {
     std::ifstream in; std::ofstream out;
     in.exceptions(std::ios::badbit|std::ios::failbit);
     out.exceptions(std::ios::badbit|std::ios::failbit);
    
     try {
      in.open(input.c_str(),std::ios::binary|std::ios::in|std::ios::out);
      out.open(output.c_str(),std::ios::binary|std::ios::out);
      in.seekg(0,std::ios::end); long int x = in.tellg(); in.seekg(0,std::ios::beg); char z;
      for(int y = 0;y < x;y++) { in.get(z); out.put(z); }
      in.close(); out.close();
     }
    
     catch(std::ios::failure&) {
      if(in.bad())   { return 0; }
      if(in.fail())  { return 0; }
      if(out.bad())  { return 0; }
      if(out.fail()) { return 0; }
     } return 1;
    
    }
    

    gelöst: so wird kein eof ausgelöst und nicht existierende dateien werden einfach erstellt...
    und die exception greifen trotzdem einwandfrei...

    es ist nicht lesbar geschrieben ich weiß...


  • Mod

    War es wirklich nötig, diesen 14 Monate alten Thread wieder zu erwecken?



  • google 1. treffer:

    http://stackoverflow.com/questions/10195343/copy-a-file-in-a-sane-safe-and-efficient-way

    von deinem code würde ich aus mehreren gründen abraten.
    ich bin mir auch ziemlich sicher, dass dieser nicht ohne warnings compiliert. (int / long vergleich in deiner schleife)

    catch(std::ios::failure&) {
      if(in.bad())   { return 0; }
      if(in.fail())  { return 0; }
      if(out.bad())  { return 0; }
      if(out.fail()) { return 0; }
     }
    return 1;
    

    ->

    catch(const std::ios::failure&)
    {
      return false;
    }
    return true;
    

    wenn dir aber exceptions ohnehin bekannt sind, wieso dann nicht einfach die exception weiterwerfen und die signatur deiner fkt zu void f(string,string) ändern.



  • ich würde dazu raten evt. die grundlagen der sprache c++ nochmal zu wiederholen bevor du weiter machst ... 🙄

    macht für mich i.wie nicht den eindruck das du weißt was du da tust und in deinen anderen beiträgen (ältere, anderes thema) festigt sich diese meinung nur.

    prinzipiell kann ich dir empfehlen ein "gutes" c++ buch zu kaufen, spontan würde mir da von ulrich breymann "der c++ programmier" einfallen und dann solltest vll erstmal die grundlagen durch arbeiten. 🙄

    ich denke dann hast du auch nicht mehr solche probleme 😉

    hoff ich konnte etwas hilfreiches beitragen 🙄
    lg


Anmelden zum Antworten