Exception macht Probleme, Fehler wird nicht abgefangen
-
Hi Leute
,bis vor kurzem habe ich Fehler noch über Rückgabewerte behndelt. Nun möchte ich das ganze über die effektiveren MFC-Exceptions machen.
Ich habe hier eine Funktion in der ich per Standarddialog eine Datei öffne, wenn ich nun von Hand den Namen einer Datei eingebe die nicht existiert möchte ich diesen Fehler abfangen !
Ich sitz schon den ganzen Tag dran aber es klappt einfach nicht und google liefert auch nichts brauchbares.Hier der Code:
void CMokkaDoc::OnFileOpen() { CFileException fe; iZaehlerNext = 0; // Wenn File öffnen Dlg geöffnet wird dann FileZähler auf 0 setzen char strFilter[] = {"NFO-Files (*.nfo)|*.nfo|*.nfo||"}; CFileDialog fileDlg(TRUE,".nfo",NULL,0,strFilter); CFile file; // Objekt der Klasse CFile erstellen if(fileDlg.DoModal()==IDOK) // Dialogfeld öffnen und Ergebnis auffangen { m_strDateiname = fileDlg.GetFileName(); // Dateinamen des gewählten Files ermitteln m_srtFilePathName = fileDlg.GetPathName(); // DateiPfad des gewählten Files ermitteln m_strFileExtension = fileDlg.GetFileExt (); // DateiEndung des gewählten Files ermitteln try { file.Open(fileDlg.GetFileName(), file.modeRead,&fe);// Ausgewählte Datei öffnen str = new TCHAR[(file.GetLength())+1]; // TChar Array auf Heap schieben damit es dynamisch wird str[(file.GetLength())] = '\0'; // TChar Array mit 0 terminieren file.Read(str, file.GetLength()); // File lesen und Array str mit Werten füllen } catch(CFileException *pe) { MessageBox(0,"Fehler","Fehler",MB_OK); } } cstrAusgabe = str; // Variable für die Ausgabe mit Inhalt(str) der Datei füllen file.Close(); // File wieder schließen UpdateAllViews (NULL); // View Aktualisieren }wäre super wenn Ihr mir helfen könntet ?!
Danke vorab

ShadowEater
-
Siehe MSDN:
While the CFile constructor will throw an exception in an error condition, Open will return FALSE for error conditions. Open can still initialize a CFileException object to describe the error, however. If you don't supply the pError parameter, or if you pass NULL for pError, Open will return FALSE and not throw a CFileException. If you pass a pointer to an existing CFileException, and Open encounters an error, the function will fill it with information describing that error. In neither case will Open throw an exception.Also einfach die Datei über den Konstrukor öffnen.
Das CFile Objekt gehört in den try/catch Block. Der Close wir dadurch unnötig.
-
MSDN CFile::Open schrieb:
While the CFile constructor will throw an exception in an error condition, Open will return FALSE for error conditions. Open can still initialize a CFileException object to describe the error, however. If you don’t supply the pError parameter, or if you pass NULL for pError, Open will return FALSE and not throw a CFileException. If you pass a pointer to an existing CFileException, and Open encounters an error, the function will fill it with information describing that error. In neither case will Open throw an exception.
Oder auf Deutsch: Open() wirft keine Exception, aber es füllt die übergebene CFileException mit den nötigen Informationen - werfen müsstest du sie schon selber, wenn du es drauf anlegst.
Alternativ kannst du dein File auch erst dort anlegen, wo du es benötigst:
try { CFile file(fileDlg.GetFileName(), file.modeRead,&fe); str = new TCHAR[(file.GetLength())+1]; str[(file.GetLength())] = '\0'; file.Read(str, file.GetLength()); } catch(CFileException *pe)//ich bin mir nicht sicher, aber solltest du nicht besser ein CFileException& fangen? { MessageBox(0,"Fehler","Fehler",MB_OK); }
-
Hi,
Danke für eure schnellen Antworten, ich hab alles so implementiert:{ CFileException fe; iZaehlerNext = 0; // Wenn File öffnen Dlg geöffnet wird dann FileZähler auf 0 setzen char strFilter[] = {"NFO-Files (*.nfo)|*.nfo|*.nfo||"}; CFileDialog fileDlg(TRUE,".nfo",NULL,0,strFilter); try { CFile file; // Objekt der Klasse CFile erstellen if(fileDlg.DoModal()==IDOK) // Dialogfeld öffnen und Ergebnis auffangen { m_strDateiname = fileDlg.GetFileName(); // Dateinamen des gewählten Files ermitteln m_srtFilePathName = fileDlg.GetPathName(); // DateiPfad des gewählten Files ermitteln m_strFileExtension = fileDlg.GetFileExt (); // DateiEndung des gewählten Files ermitteln file.Open(fileDlg.GetFileName(), file.modeRead,&fe);// Ausgewählte Datei öffnen str = new TCHAR[(file.GetLength())+1]; // TChar Array auf Heap schieben damit es dynamisch wird str[(file.GetLength())] = '\0'; // TChar Array mit 0 terminieren file.Read(str, file.GetLength()); // File lesen und Array str mit Werten füllen } } catch(CFileException *pe) { MessageBox(0,"Fehler","Fehler",MB_OK); } cstrAusgabe = str; // Variable für die Ausgabe mit Inhalt(str) der Datei füllen // file.Close(); // File wieder schließen UpdateAllViews (NULL); // View Aktualisieren }leider funktioniert es immer noch nicht

Gruß

ShadowEater
-
P.S.: Ich bekomme nur "Debug Assertion failed..."
Gruß
ShadowEater
-
Hi ;),
kann mir da niemand weiterhelfen, es will einfach nicht klappen, liegt es daran dass ich das ganze in einem Standarddialog mache oder so ?
Das sonderbare ist, wenn ich Exceptions in normalem C++ verwende klappt die Sache.
Aber hier bekomme ich nach Eingabe eines nicht existenten Files nur eine Debug Assertion.Danke

ShadowEater
-
Hast Du nicht mal die Doku gelesen?
Die Open Methode wirfst so keine Exception!Nimm den Konstruktor!
CFile file(fileDlg.GetFileName(), file.modeRead);
-
Wenn Du schon open benutzt, dann den Fehler richtig behandeln.
if( file.Open(fileDlg.GetFileName(), file.modeRead,&fe);// Ausgewählte Datei { //weiter ... } else { // hier Fehlerbehandlung nicht über catch char expbuf[256]; fe.GetErrorMessage((LPTSTR)expbuf,255); TRACE(expbuf); }
-
Einfacher wäre dann
if( file.Open(fileDlg.GetFileName(), file.modeRead,&fe);// Ausgewählte Datei { //weiter ... } else throw &fe;fe sollte dann außerhalb des Try/Catch Blockes liegen!
-
moeglichkeit waere auch in dem Try block
/*..*/ bool FileExist(const CString& strFileName); /*..*/ try { /*..*/ if(!FileExist(m_srtFilePathName)) throw _T("File not exist"); /*..*/ catch( /*..*/
-
Doch ich hab die Doku gelesen, hab aber trotzdem ne Fehlermeldung bekommen, Danke jetzt klappts !
Gruß
SE