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 AntwortenCyax
-
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 mitifstream
erreichst. std::fstream
und die anderen Dateistreams initialisiert man praktisch immer mit dem Dateinamen-Konstruktor. Das heißt in deinem Beispiel: Nicht die Memberfunktionopen
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 einint
zurück, es gibt aber keinreturn
-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.
- Immer den Dateistream verwenden, den man braucht.
-
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 beifstream f( GetInstallDirectory("\\install.status").c_str() );
bzw bei "GetInstallDirectory"
Aber trotzdem danke für deine HilfeGruß
Cyax
-
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. :pWas 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 inGetInstallDirectory
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.