NewBee braucht Hilfe bei try...catch Problem
-
hmm also ich verstehs nicht...
So funktioniert der Code einwandfrei:
// lcopy.cpp: Hauptprojektdatei. #include "stdafx.h" using namespace System; using namespace System::IO; using namespace System::Text; int main(array<System::String ^> ^args) { // Prüfen, ob zwei Argumente eingegeben sind if (args->Length != 2) { Console::WriteLine("Fehlende Argumente!"); return 0; } /*StreamReader ^datei_von; try {*/ StreamReader ^datei_von = gcnew StreamReader(args[0], Encoding::GetEncoding("Windows-1252")); /* } catch (FileNotFoundException ^e) { if (datei_von == nullptr) { Console::WriteLine("{0} konnte nicht geöffnet werden.",args[0]); datei_von->Close(); return 0; } else { Console::WriteLine("Allgemeiner Fehler!"); datei_von->Close(); return 0; } }*/ StreamWriter ^datei_nach = gcnew StreamWriter(args[1]); while (datei_von->Peek() != -1) { datei_nach->Write(datei_von->Read()); } datei_von->Close(); datei_nach->Close(); return 0; }Nehme ich die auskommentierten Zeilen wieder rein, erstellt er zwar das Programm, allerdings stürzt er dann ab mit hinweis auf ein nicht definierte Objektinstanz...
-
Du prüfst in Zeile 25 auf einen Nullpointer und rufst in Zeile 28 trotzdem Close() auf. Ist das erste was mir auffällt.
Edit: ^datei_von wird außerdem zweimal definiert.
-
connan schrieb:
Du prüfst in Zeile 25 auf einen Nullpointer und rufst in Zeile 28 trotzdem Close() auf. Ist das erste was mir auffällt.
Edit: ^datei_von wird außerdem zweimal definiert.Hallo Connan,
stimmt, das habe ich inzwischen auch gemerkt und rausgenommen. Ändert aber nichts an dem Grundproblem.
Sobald ich die Datei innerhalb des try-blocks öffne, kriegt er das nicht mehr hin, liest datei_von hat also einen undefinierbaren wert. Wenn ich datei_von vorher nicht deklariere, geht der kompiler gar nicht erst durch...
keine Ahnung was das soll, bin ziemlich ratlos...
Wie gesagt, ohne try...catch funktioniert der code wie gewünscht...
-
So, habs nun geschafft...
Das Problem war, dass (neben ein paar anderen Unsauberkeiten im Code) ^datei_von seine Referenz verliert, wenn der try-block beendet wird. Habe nun alles in den Block gepackt und nun gehts..
Der code, wie er nun bei mir läuft:
// lcopy.cpp: Hauptprojektdatei. #include "stdafx.h" using namespace System; using namespace System::IO; using namespace System::Text; int main(array<System::String ^> ^args) { // Prüfen, ob zwei Argumente eingegeben sind if (args->Length != 2) { Console::WriteLine("Fehlende Argumente!"); return 0; } StreamReader ^datei_von; try { StreamReader ^datei_von = gcnew StreamReader(args[0], Encoding::GetEncoding("Windows-1252")); StreamWriter ^datei_nach = gcnew StreamWriter(args[1]); while (datei_von->Peek() != -1) { datei_nach->Write(datei_von->Read()); } datei_von->Close(); datei_nach->Close(); } catch (FileNotFoundException ^e) { Console::WriteLine("{0} konnte nicht geöffnet werden.",args[0]); return 0; } catch (Exception ^e) { Console::WriteLine("Allgemeiner Fehler!"); datei_von->Close(); return 0; } Console::Write("Bitte q eingeben zum beenden: "); Console::ReadKey("q"); return 0; }Beste Grüße und Danke an Euch beide

-
Nein, so gehts nicht. Es kompiliert vielleicht... aber sinnvoll ist es nicht.
Dein Problem hat nichts mit "Referenz verlieren" zu tun (das gibts nämlich nicht).
Dein Problem sind Scopes. Und hier im speziellen der Scope des try- catch Klausel.Der üblich Aufbau sieht so aus:
StreamReader^ file = nullptr; try { file = gcnew StreamReader("dein file name", Encoding::Default); // benutze den stream } catch (FileNotFoundExeption^ ex) { if (file != nullptr) { file->Close(); } }Falls file (wie bei Dir) innerhalb des try- Blockes dekl. und initialisiert ist, ist der Gültigkeitsbereich (=Scope) auf diesen eingeschränkt und somit ausserhalb und im catch- Block nicht zugreifbar (dafür sorgt der Kompiler).
Bei deinem Code ist ein Gemisch!
Simon
Edit: Hier könnte übrigens der finally- Block gebraucht werden. Google doch mal danach.
-
Hallo Simon,
danke noch mal für Die Erläuterung... (langsam fange ich an es zu verstehen :D)
der Finally Block wird ja in jedem Fall ausgeführt... da ich den stream aber noch brauche macht es ja keinen sinn, hier wieder den Stream zu schließen... und soweit ich es verstanden habe, sollen die Blöcke beieinanderstehen... oder?
Verstehe also gerade nicht ganz, wozu ich hier den finally-block einbauen sollte...
-
Hier noch ein Bsp.:
#include "stdafx.h" using namespace System; using namespace System::IO; using namespace System::Text; void CopyFile(String^ sourceFileName, String^ destinationFileName) { StreamReader^ sourceStream = nullptr; try { sourceStream = gcnew StreamReader(sourceFileName, Encoding::Default); StreamWriter^ destinationStream = nullptr; try { destinationStream = gcnew StreamWriter(destinationFileName); int value; while((value = sourceStream->Read()) != -1) { destinationStream->Write(value); } } finally { if (destinationStream != nullptr) { destinationStream->Close(); } } } finally { if (sourceStream != nullptr) { sourceStream->Close(); } } } int main(array<System::String ^> ^args) { try { CopyFile("test.txt", "copy of test.txt"); } catch(FileNotFoundException^ ex) { Console::WriteLine(ex->ToString()); } return 0; }
-
Danke für das Beispiel... Müsste man nicht in der Funktion mit catch die FileNotFound Exeption abfangen... wieso hast Du den Aufruf der Funktion nochmal in einen try-block gepackt. Hab ein bischen probiert und habe die exception gleich oben abgefangen... dann ist aber der untere try-block eigentlich überflüssig oder?
PS: Gibt es eigentlich einen Unterschied zwischen deiner und meienr While-Schleife?
// lcopy.cpp: Hauptprojektdatei. #include "stdafx.h" using namespace System; using namespace System::IO; using namespace System::Text; void CopyFile(String^ sourceFileName, String^ destinationFileName) { StreamReader^ sourceStream = nullptr; try { sourceStream = gcnew StreamReader(sourceFileName, Encoding::Default); StreamWriter^ destinationStream = nullptr; try { destinationStream = gcnew StreamWriter(destinationFileName); int value; while((value = sourceStream->Read()) != -1) { destinationStream->Write(value); } } finally { if (destinationStream != nullptr) { destinationStream->Close(); } } } catch (FileNotFoundException ^ex) { Console::WriteLine(ex->FileName + " konnte nicht geöffnet werden."); } finally { if (sourceStream != nullptr) { sourceStream->Close(); } } } int main(array<System::String ^> ^args) { // Prüfen, ob zwei Argumente eingegeben sind if (args->Length != 2) { Console::WriteLine("Fehlende Argumente! Bitte lcopy <ausgangsdatei> <zieldatei> eingeben."); return 0; } CopyFile(args[0],args[1]); Console::Write("Bitte q eingeben zum beenden: "); Console::ReadKey("q"); return 0; }
-
Danke für das Beispiel... Müsste man nicht in der Funktion mit catch die FileNotFound Exeption abfangen... wieso hast Du den Aufruf der Funktion nochmal in einen try-block gepackt. Hab ein bischen probiert und habe die exception gleich oben abgefangen... dann ist aber der untere try-block eigentlich überflüssig oder?
Ist halt Exception Philosophie... fange nur Exceptions bei denen du auch eine Lösung dazu hast (und zwar an der Stelle, ander der Du die Lösung hast).
Meine Lösung sieht so aus, dass ich auf die Console eine Meldung ausgebe. Dies ist aber nicht Teil der CopyFile Funktion, denn die soll NUR kopieren (versuchen). (einfach ausgedrückt...)PS: Gibt es eigentlich einen Unterschied zwischen deiner und meienr While-Schleife?
Ja, Du prüfst immer zuerst den anstehenden Wert und ich hole in immer raus.
Geht beides.. aber warum prüfen, wenns nicht nötig ist...Simon
-
ok. Vielen Dank nochmal für die Tipps und Hilfe!!!