Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » io-Probleme

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
15.12.2004, 12:10 Uhr
(un)wissender
Niveauwart


Folgendes Programm soll einfach nur eine Datei zeilenweise auslesen und dann sofort wieder in die selbe Stelle zurückschreiben. Das funzt aber nicht, eine Ausnahme mit der Nacrhricht "io failure" wird geworfen.
Ist das überhaupt möglich, was ich da möchte?


C++:
/*
Inhalt von test.txt

Achsvertaerker@VD600@1§1
Achsvertaerker@VD600@2§1
Achsvertaerker@VD600@3§1
Achsvertaerker@VD600@4§1
*/


#include <iostream>
#include <fstream>

int main()
{
    //Datei
    std::fstream io("test.txt");

    //Immer Ausnahme auslösen
    io.exceptions(std::ios::goodbit | std::ios::eofbit | std::ios::failbit | std::ios::badbit);
    
    //Hier schreiben wir rein
    std::string buffer;
    
    try
    {
        //Position merken
        std::size_t pos = 0;
        
        //Solange Datei nicht ganz gelesen ist...
        while(!io.eof())
        {                        
            //An aktuelle Einleseposition setzen.
            std::istream& in  = io.seekg(pos, std::ios::beg);    
        
            //Vor dem Lesen merken, wo wir waren.
            std::size_t beforeRead = pos;
        
            //Lesen
            std::getline(in, buffer);
        
            //Was haben wir gelesen?
            std::cout << "Read: " << buffer << std::endl;
    
            //Neue Position merken
            pos = in.tellg();

            //Zur Kontrolle ausgeben
            std::cout << "pos: " << pos << std::endl;

            //Nun die Ausgabe, wir wollen das wieder schreiben, was wir gelesen haben.
            std::ostream& out = io.seekp(beforeRead, std::ios::beg);
            
            //Schreiben
            out << buffer << std::endl;

            //Was haben wir geschreiben?
            std::cout << "Wrote: " << buffer << std::endl;        
        }
    }
    catch(std::exception& e)
    {
        //WAs ist schief gelaufen?
        std::cout << e.what()<< std::endl;
    }
    
    //Stream schließen.
    io.close();
}


--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
15.12.2004, 12:46 Uhr
virtual
Sexiest Bit alive
(Operator)


Warum benutzen Windows User eigentlich immer Schrott compiler? - Weil sie ein Schrott OS verwenden? - Seis drum, Anmerkungen im Quelltext mit VIRTUAL gekennzeichnet:

C++:
/*
Inhalt von test.txt

Achsvertaerker@VD600@1§1
Achsvertaerker@VD600@2§1
Achsvertaerker@VD600@3§1
Achsvertaerker@VD600@4§1
*/


#include <iostream>
#include <fstream>
#include <string>           // VIRTUAL Missing gemäß ISO C++
#include <stdexcept>        // VIRTUAL Missing gemäß ISO C++
int main()
{
    //Datei
    // std::fstream io("test.txt"); // VIRTUAL den ctor gibts nicht gemäß ISO C++...
    std::fstream io("test.txt", std::ios::in|std::ios::out|std::ios::binary); // VIRTUAL ...nimm besser den
    ... rest ist okay ...


Ein Hinweis noch bzgl. des Openmodes beim ctor von fstream: ich empfehle dringend, std::ios::binary zu verwenden, weil die seek-Operationen im Textmode wegen des Übersetzens des Zeilenumbriuches nicht verlässlich sind.
Dein Absturz rphrt vermutlich daher, daß Deine "STL" Implementierung einen ctor mit "const char*" bereitstellt (den gibt es eigentlich garnicht). Bitte schau in die Doku deines Compilers; ich vermute er ist so drauf, daß er die Datei dann im Readonly Mode öffnet...
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
15.12.2004, 13:33 Uhr
(un)wissender
Niveauwart


Jo, der Konstruktor wars, fiese Falle.
Aber jetzt wird alles geschrieben und am Ende gibt es immer eine Exception (failure), warum? Scheinbar funzt der eof test nicht...
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
15.12.2004, 13:45 Uhr
virtual
Sexiest Bit alive
(Operator)


Na: du sagst doch explizit, daß du im eof ne Exception haben möchtest...
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
15.12.2004, 16:34 Uhr
(un)wissender
Niveauwart


Hm, daran liegt es nicht, es ist halt nicht eof, sondern failure. Ich habe es fast, werde mit aber wohl mein eigenes getline basteln müssen, da das Verhalten nicht portabel zu sein scheint.
Das eof-Zeichen wird leider von STLport.getline ignoriert und dann gibt es failure...
Echt harte Nuss das ganze, hätte ich nicht gedacht!
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
15.12.2004, 17:21 Uhr
virtual
Sexiest Bit alive
(Operator)


Doch: das eofbit wird ja nicht allein gesetzt, sondern mit dem faillurebit zusammen.
Zur verdeutlichung:

C++:
io.exceptions(std::ios::eofbit); // NUR EOF
try {
// do something with io

    if (!io) {
     // Irgendein fehler
    }
}
catch(...) {
   // EOF erreicht
}


Dagegen:

C++:
io.exceptions(std::ios::eofbit|std::ios::badbit|std::ios::failbit); // NICHT NUR EOF
try {
// do something with io

}
catch(...) {
   if (!io.eof()) {
      // Fehler
    }
    else{
      // EOF erreicht
    }
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
15.12.2004, 21:15 Uhr
(un)wissender
Niveauwart


Das ist ja Dreck hoch zehn, du hast recht. Sobald eof gelesen wird, wird das failbit gesetzt. Was soll das? Das ist doch kein Fehler, da man eof immer lesen muss!

Das hier tut endlich, was es soll...allerdings wird entweder EOF nie erreicht oder es wird keine Exception geworfen, vielleicht weil das failbit zusammen mit eofbit in diesem Fall doch nicht gesetzt wird. Versteh das einer, ich nicht!


C++:
#include <stdexcept>
#include <iostream>
#include <fstream>
#include <string>

int main()
{
    //Datei
    std::fstream io("test.txt", std::ios::in | std::ios::out | std::ios::binary);

    //Immer Ausnahme auslösen
    io.exceptions(std::ios::failbit|std::ios::badbit);
    
    //Hier schreiben wir rein
    std::string buffer;
    
    try
    {
        std::size_t pos = 0;
        const std::size_t FILE_SIZE = io.seekg(0, std::ios::end).tellg();
        io.seekg(0, std::ios::beg);
        
        //Solange Datei nicht ganz gelesen ist...
        while(!io.eof() && pos < FILE_SIZE)
        {    
            //An aktuelle Einleseposition setzen.
            std::istream& in  = io.seekg(pos, std::ios::beg);    
        
            //Vor dem Lesen merken, wo wir waren.
            const std::size_t beforeRead = pos;
        
            //Lesen
            std::getline(in, buffer);
        
            //Was haben wir gelesen?
            std::cout << "Read: " << buffer << std::endl;
    
            //Neue Position merken
            pos = in.tellg();

            //Zur Kontrolle ausgeben
            std::cout << "pos: " << pos << std::endl;

            //Nun die Ausgabe, wir wollen das wieder schreiben, was wir gelesen haben.
            std::ios::iostate state = io.rdstate();
            io.clear();

            std::ostream& out = io.seekp(beforeRead, std::ios::beg);
                
            //Schreiben
            out << buffer;
        
            //Was haben wir geschreiben?
            std::cout << "Wrote: " << buffer << std::endl;
            io.setstate(state);    
        }
    }
    catch(std::exception& e)
    {
        //Was ist schief gelaufen?
        std::cout << e.what()<< std::endl;
    }
    
    //Stream schließen.
    io.close();
}



--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
16.12.2004, 07:13 Uhr
virtual
Sexiest Bit alive
(Operator)


Na, in dem Code wird natürlich () EOF nie erreicht: EOF wird genau dann gesetzt, wenn das letzte Zeichen des Streams gelesen wurde und ein Versuch unternommen wurde, das nächste (nicht existierende) Zeichen zu lesen.

Letzteres versuchst Du in Deinem Programm ja nicht, weil pos<FILE_SIZE in der Bedingung steht (Übrigens schreibt man in C/C++ eigentlich fast alles klein, Macros und Konstanten bilden da eine Ausnahme, FILE in C wegen seiner herausragenden Bedeutung auch)

Semantisch korrekt ist das schon alles:

eof Bit wird gesetzt, wenn jemand versucht, nach Dateiende etwas zu lesen

fail Bit wird gesetzt, wenn die letzte Leseoperation schief ging, aber Stream noch prinzipiell weiterhin gebrauchtbar werden kann. (Dh. insbes. daß eof fail impliziert). Typische Situation: Man will eine Ziffer lesen, aber ein ordinärer Buchstabe wird gelesen.

bad Bit wird gesetzt, wenn die letzte Leseoperation schief ging, aber Stream aber corrupt ist. Typische Situation: Bei einem Socket stream bekommt man einen timeout und die Verbindung wird getrennt.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 16.12.2004 um 07:14 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
16.12.2004, 08:52 Uhr
(un)wissender
Niveauwart



Zitat von virtual:

Na, in dem Code wird natürlich () EOF nie erreicht: EOF wird genau dann gesetzt, wenn das letzte Zeichen des Streams gelesen wurde und ein Versuch unternommen wurde, das nächste (nicht existierende) Zeichen zu lesen.



Hm, macht das Sinn? Also mal ganz logisch würde ich eof setzen, sobald eof gelesen wurde und kein failbit, das würde ich erst setzen, wenn auf ein Zeichen hinter eof zugeriffen wird.


Zitat von virtual:

[...](Übrigens schreibt man in C/C++ eigentlich fast alles klein, Macros und Konstanten bilden da eine Ausnahme, FILE in C wegen seiner herausragenden Bedeutung auch)


FILE_SIZE ist eine Konstante, steht zumindest const vor.

Also, ich glaube mein gedankliches Problem liegt darin, dass ich nicht will, dass eof fail impliziert, das nervt und ist in Java auch anderes gehandhabt (soweit ich mich erinnern kann).
Ich muss mich wohl mal mehr mit C++-Streams auseinandersetzen, als bloß std::cout zu schreiben.
Danke auf jeden Fall für die Ausführungen und Hilfe.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: