iostreams und errno?



  • Das beschäftigt mich jetzt schon länger, aber ich finde einfach nirgends was dazu: wenn man fopen() verwendet und das nicht funktioniert, kann man mittels errno herausfinden, warum es nicht gegangen ist und mit strerror() eine Fehlermeldung generieren. Was macht man aber, wenn ein ifstream.open() nicht funktioniert? Wie kommt man da an eine Fehlermeldung? Ich hab's gerade in VC++ 7.1 ausprobiert - da kann man errno verwenden, aber solange das nicht in Stein gemeißelt ist, möchte ich mich eigentlich nicht darauf verlassen.



  • Hallo,

    die C++-Standardbibliothek nutzt errno nicht. Schau mal hier:

    http://www.cppreference.com/cppio/open.html



  • Na gut, dann formuliere ich halt meine Frage um. Woher weiß ich dann, warum das open() fehlschlägt? (Nicht gefunden, keine Berechtigung, Disk error, ...)



  • hier:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang98/html/_iostream_ifstream.3a3a.open.asp

    bzw. ios::bad und ios::fail.

    genauere fehlerbeschreibungen bekommt man nur durch andere, wohl auch bs-speziefische funktionen.



  • Danke für eure Mühe, aber ich kenne mich in C++ eigentlich sehr gut aus und weiß auch, wo ich nachschauen muss. Folglich kenne ich bad und fail usw. schon.

    Ich kann es kaum glauben, dass ein wunderbar plattformunabhängiger Mechanismus (errno/strerror) durch einen zugegebenermaßen ebenfalls plattformunabhängigen anderen Mechanismus ersetzt werden soll, der absolute Basisfunktionalität beinhart verweigert.

    genauere fehlerbeschreibungen bekommt man nur durch andere, wohl auch bs-speziefische funktionen.

    Auch das ist mir bewusst, aber das bedeutet, dass man in den Code der C++-Library reinschauen muss und bei jedem noch so winzigen Upgrade erneut checken muss, ob die Vorgehensweise des Tages denn auch noch so funktioniert, wie man sie implementiert hat. Na Mahlzeit!

    Jetzt hatte ich wirklich nach Jahren mal ernsthaft vor, von fopen/printf auf iostreams umzusteigen, aber wenn das so ist, bleibe ich wohl bei bewährten Mitteln.



  • Es ist doch unwichtig den genauen Grund zu erfahren!



  • Herr Gott, dann benutzt boost::filesystem.



  • Artchi schrieb:

    Herr Gott, dann benutzt boost::filesystem.

    wie soll das damit bitteschön gehen?



  • boost::filesystem wirft spezialisierte Exceptions, die mehr aussagen als die von der Standardlib.



  • aber dort gibt es doch gar keine klasse für dateien



  • Artchi schrieb:

    Herr Gott, dann benutzt boost::filesystem.

    Hmm, mal sehen. Vielleicht kann das ja wirklich was...
    Danke für den Tip.

    EDIT: Ich hoffe nur, dass das auch UNC-Namen kann unter Windows.



  • hmmmmmmmm schrieb:

    aber dort gibt es doch gar keine klasse für dateien

    Ehm, neee, die machen eine Dateisystem-Librarie ohne Datei-Klassen. Neee, is' klar.



  • Ringding schrieb:

    EDIT: Ich hoffe nur, dass das auch UNC-Namen kann unter Windows.

    Ehm, du meinst UTF16? Also gerade da hapert es glaub ich noch an der Lib, obwohl die Lib ansonst super ist. Hat jemand erst letztens in der boost-Mailingliste angesprochen, das er an der Stelle Schwierigleiten hatte. Aber probier es einfach mal aus.



  • dann sag bitte wie die heißt.



  • Nein, nicht UTF16. Sondern alles, was mit "\" anfängt (für Zugriff auf Netzwerkshares hauptsächlich, man kann damit aber auch auf Diskettenlaufwerke, Festplattenpartitionen, USB-Devices und weiß der Geier was noch zugreifen).



  • hmmmmmmmmm schrieb:

    dann sag bitte wie die heißt.

    Schau doch einfach mal in die doku rein. Mit den folgenden MItteln arbeitet kann man auf das Filesystem zugreifen:

    Mit boost::filesystem::path bestimmst du erstmal ein Verzeichnis oder eine Datei.

    Mit boost::filesystem kannst du auf path Operationen durchführen (iterieren, löschen, kopieren, bestimmte Attribute prüfen usw.)

    Mit boost::filesystem::fstream kannst du auf path letztendlich den Inhalt streamen.

    Wenn das mal nicht nützliche Funktionen und Klassen sind, die was mit Dateien zu tun haben, dann weiß ich auch nicht. 😃



  • Ringding schrieb:

    Nein, nicht UTF16. Sondern alles, was mit "\" anfängt (für Zugriff auf Netzwerkshares hauptsächlich, man kann damit aber auch auf Diskettenlaufwerke, Festplattenpartitionen, USB-Devices und weiß der Geier was noch zugreifen).

    Achso! Ehm... hem, kann ich jetzt leider auch nicht sagen, war noch nie in der Situation. Aber wenn ich die Doku richtig verstehe, wurde dies schon beachtet aber noch nicht ausführlich getestet. Weiterhin mußt du keine Backslashes benutzen sondern Slashes, das, wird intern dann umgewandelt. Also "//share" benutzen und nicht "\\share".



  • Ok das habe ich alles schon in der Dokumentation gesehen aber das hilft bei Ringdings Problematik doch überhaupt nichts?!?

    Also da ist ja jetzt keine eigene Klasse für die Dateiverarbeitung drin wie std::fstream. boost::filesystem::fstream ist ja nur dafür da das alle Funktionen Path& aktzeptieren.



  • Es wird ihm in sofern mehr helfen, das er aussagekräftigere Exceptions geworfen bekommt. Welche man hier sehen kann:
    http://www.boost.org/libs/filesystem/doc/exception.htm

    Ich finde das schon um einiges besser. Er kann z.B. auch vorher mit den operations abfragen ob eine Datei überhaupt existiert, oder ob sie überhaupt eine Datei und kein Verz. ist. Und selbst wenn das alles geklappt hat und er versucht z.B. eine schreibgeschützte Datei zu beschreiben oder zu löschen, bekommt er eine Exception mit einem read_only_error und einer Betriebssystem-Message als Errortext die er dem User präsentieren kann.

    Wenn man vielleicht noch mehr haben will (was wohl seltener der Fall sein dürfte) müsste er letztendlich direkt sein OS zugreifen. Aber boost::filesystem versucht schon das meiste zu lösen.



  • Und selbst wenn das alles geklappt hat und er versucht z.B. eine schreibgeschützte Datei zu beschreiben oder zu löschen, bekommt er eine Exception mit einem read_only_error und einer Betriebssystem-Message als Errortext die er dem User präsentieren kann.

    Welche Funktion wirft die Exception beim beschreiben?

    Beim Löschen ists ja logisch, da gibts ne extra Funktion.


Log in to reply