C++ Frage



  • Hallo Leute,
    und zwar bin ich grad dabei ein kleines Programm zu schreiben
    in welchem ich unter anderem Dateipfade ermittel und somit Textdateien
    ausfindig machen möchte. Ich hab hier jetzt eine Funktion mit der ich den aktuellen Pfad auslese:

    int GetInstallDirectory(string install)
    {
        CHAR installPath[MAX_PATH];
        GetModuleFileName(NULL, installPath, MAX_PATH-1);
        *strrchr(installPath, '\\') = 0;
        string com3 = "\\install";
        string insPath = installPath + com3;
        string finalInstallPath = insPath + install;
        cout<<finalInstallPath<<endl;
    }
    

    nun möchte ich die Variable finalInstallPath verwenden um eine Textdatei zu öffnen bzw zu überprüfen ob diese überhaupt vorhanden ist.

    void checkInstallation()
    {
        GetInstallDirectory("\\install.status");
        fstream f;
        f.open(GetInstallDirectory("\\install.status"), ios::out);
        if(!f)
        {
            cout<<"Not Installed"<<endl;
            //usw...
    

    Allerdings funktioniert es nicht die Datei zu öffnen solange ich "GetInstallDirectory" als Variable verwende...
    Hat jemand ne idee wie ich einfach den Pfad als Variable (am besten als Char) in Kombination mit fstream verwenden kann...
    Danke für alle Antworten 😉

    Cyax


  • Mod

    Allerdings funktioniert es nicht die Datei zu öffnen solange ich "GetInstallDirectory" als Variable verwende...

    Erstmal einige Tipps im Voraus:

    • Immer den Dateistream verwenden, den man braucht. std::fstream liest und schreibt, wohingegen du wahrscheinlich nur Lesen willst, was du mit ifstream erreichst.
    • std::fstream und die anderen Dateistreams initialisiert man praktisch immer mit dem Dateinamen-Konstruktor. Das heißt in deinem Beispiel: Nicht die Memberfunktion open verwenden.
    fstream f(GetInstallDirectory("\\install.status"), ios::out);
    
    • Öffnest du eine Datei zum schreiben, wird sie immer angelegt, falls sie nicht existiert. Prüfe das also eher mit ifstream, wobei das passende Flag dort schon gesetzt ist ( ios_base::in ).
      ➡
    ifstream f( GetInstallDirectory("\\install.status").c_str() ); // Sollte dein Compiler C++11-kompatibel sein, lass das .c_str() weg
    
    • Die unnötigen Zwischenobjekte in der Funktion kannst du weglassen.
    string finalInstallPath = installPath + ("\\install" + install);
        cout << finalInstallPath << '\n'; // Und kein endl, das brauchst du hier sicher nicht
    

    Die richtigen Fehler sind bei dir folgende. Zuallererst gibt GetInstallDirectory laut Rückgabetyp ein int zurück, es gibt aber kein return -Statement in der Funktion. Das führt zu undefiniertem Verhalten. Deine Funktion sollte wohl eher den Dateipfad zurückgeben.

    Des weiteren könnte strrchr auch nichts finden. Diesen Fehler musst du irgendwie behandeln, denn sonst dereferenzierst du einen Nullzeiger (auch UB).
    Das führt zu folgender Definition:

    std::string GetInstallDirectory(string install)
    {
        char installPath[MAX_PATH];
        GetModuleFileName(NULL, installPath, MAX_PATH); // Wozu die -1? Passen doch MAX_PATH viele rein. 
        char const* ptr = strrchr(installPath, '\\');
        if( ptr )
        {
            *ptr = '\0';
            return installPath + ("\\install" + install);
        }
        return std::string(); // Das ist die Fehlerbehandlung. Es könnte auch eine Exception geworfen werden, fall das angebracht ist.
    }
    

    Alles ungetestet.

    Edit: Wie ich gerade lese, ist in Windows-XP GetModuleFileName so definiert, dass der String, den die Funktion in den Parameter reinschreibt, nicht null-terminiert ist. Das musst du evt. per Präprozessor-Direktive behandeln.



  • Hallo,
    erstaml danke für deine ausführliche Antwort.
    Allerdings hab ich jetzt mal alle deine Tipps befolgt, aber das Programm
    funktioniert nicht wenn ich "checkInstallation" aufrufe. Es stürzt besser
    gesagt ab.
    Die Funktion sieht jetzt so aus:

    void checkInstallation()
    {
        fstream f( GetInstallDirectory("\\install.status").c_str() );  //ifstream                                               
    //hat leider auch nicht gefunkt: Extrem viele Errors vom Compiler
        if(!f)
        {
            cout<<"Not Installed"<<endl;
            //usw
    

    GetInstallDirectory hab ich von dir übernommen, der Compiler jedenfalls spuckt
    keine Fehler aus. Ich hab ehrlich gesagt keine Ahnung woran das liegen
    könnte...
    Ich hatte so ein ähnliches Problem schon mal als ich versucht habe mit fstream
    einen Pfad aus einer Variable aufzurufen, welcher sogar existierte. Dann ist immer das Programm abgeschmiert, wenn der Pfad absichtlich falsch war, hats funktioniert, aber das ist ja nicht Sinn und Zweck meines Programms 😕
    Hast du vielleicht eine Idee? Also so wie s aussieht schaffts die Funktion "checkInstallation nicht mal bis zur if, weil ich versucht habe davor etwas auszugeben, aber das hat auch nicht gefunkt ➡ also liegst vermutlich bei

    fstream f( GetInstallDirectory("\\install.status").c_str() );
    

    bzw bei "GetInstallDirectory"
    Aber trotzdem danke für deine Hilfe 🙂

    Gruß
    Cyax


  • Mod

    ifstream hat leider auch nicht gefunkt: Extrem viele Errors vom Compiler

    Das ist seltsam. Poste mal diese Fehler.

    Und warum das Programm bei GetInstallDirectory abschmiert, weiß ich auch nicht. Kann ich auch gerade nicht testen, weil ich unter *nix bin, und zu faul zum Umbooten. :p

    Was mir nur gerade auffällt, ist folgendes: Du kannst auch einfach die Kommandozeilenparameter benutzen, um an den Pfad des Programms zu kommen. Dafür brauchst du keine WinAPI-Funktion.

    Ändere das ganze mal ab zu

    std::string GetInstallDirectory(string install)
    {
        std::string installPath(MAX_PATH);
        GetModuleFileName(NULL, &installPath[0], MAX_PATH);
    
        auto pos = installPath.find_last_of("\\/"); // Falls es am Slash liegt, sonst geht auch .rfind('\\')
        if( pos != std::string::npos )
            return installPath.substr(0, pos) + "\\install" + install;
    
        throw std::runtime_error{};
    }
    

    Es stürzt besser
    gesagt ab.

    Das ist nie eine ausreichende Fehlerbeschreibung. Kannst du das ganze Debuggen?
    Oder zumindest versuchen, etwas in GetInstallDirectory auszugeben? Dann findest du möglicherweise, an welcher Stelle es abstürzt.



  • Die Fehler vom Compiler post ich nachher.
    Aber was die Fehlerbeschreibung angeht kann ich nur sagen das das Debuggen einwandfrei funktioniert,
    das Programm aber bei Aufruf der GetInstallDirectory Funktion in fstream f; abschmiert. Also es kommt dann von Windows die Fehlermeldung: "Das Programm funkt nicht mehr... Programm schleißen oder online nach Lôsung suchen "



  • Vermutlich SIGSEGV.
    Macht dein Programm noch mehr als das.
    Hantierst du irgendwo mit Pointern?



  • Ja ich mache in meinem Programm noch mehr...
    Aber alles andere ist so zu sagen isoliert. Also nur die Funktionen
    GetInstallDirectory und checkInstallation...
    Das sind übrigensd die Fehler bei ifstream:

    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp||In function 'void checkInstallation()':|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|error: no match for 'operator<<' in 'f << "1"'|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note: candidates are:|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\basic_string.h|2750|note: template<class _CharT, class _Traits, class _Alloc> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::basic_string<_CharT, _Traits, _Alloc>&)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\basic_string.h|2750|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<_CharT, _Traits>'|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|469|note: template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, _CharT)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|469|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<_CharT, _Traits>'|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|474|note: template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, char)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|474|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<_CharT, _Traits>'|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|480|note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, char)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|480|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<char, _Traits>'|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|486|note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, signed char)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|486|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<char, _Traits>'|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|491|note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, unsigned char)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|491|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<char, _Traits>'|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|511|note: template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const _CharT*)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|511|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<_CharT, _Traits>'|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\ostream.tcc|323|note: template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const char*)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\ostream.tcc|323|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<_CharT, _Traits>'|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|528|note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const char*)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|528|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<char, _Traits>'|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|541|note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const signed char*)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|541|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<char, _Traits>'|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|546|note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const unsigned char*)|
    c:\program files (x86)\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\ostream|546|note:   template argument deduction/substitution failed:|
    C:\Users\Moritz\Desktop\CPP\CE 4.0\tool.cpp|59|note:   'std::ifstream {aka std::basic_ifstream<char>}' is not derived from 'std::basic_ostream<char, _Traits>'|
    ||=== Build finished: 35 errors, 0 warnings ===|
    

    Achja, was ist

    SIGSEGV

    ?



  • Du scheinst offenbar deinen Filestream auch für Ausgabe zu benutzen, deshalb geht das nicht, wenn du daraus einen ifstream machst, der kann nämlich nur lesen. Es ist aber trotzdem besser zwei getrennte Streams zu haben, einen fürs lesen und danach einen fürs Schreiben. Dieses parallele Lesen schreiben ist immer ein wenig blöd.
    Und SIGSEGV steht für Signal Segmentation Fault. Ein Segmentation Fault oder kurz Segfault steht für Schutzverletzung. Dein Programm schreibt in Speicher, der für ein anderes Programm reserviert ist.


Log in to reply