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


  • Mod

    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


  • Mod

    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);
    }
    

  • Mod

    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


Anmelden zum Antworten