2010-05-19 14 views
15

Ich brauche einen plattformübergreifenden Weg, um das aktuelle Arbeitsverzeichnis zu bekommen (ja, getcwd macht was ich will). Ich dachte, dies könnte den Trick tun:Was ist eine plattformübergreifende Möglichkeit, das aktuelle Verzeichnis zu erhalten?

#ifdef _WIN32 
    #include <direct.h> 
    #define getcwd _getcwd // stupid MSFT "deprecation" warning 
#elif 
    #include <unistd.h> 
#endif 
#include <string> 
#include <iostream> 
using namespace std; 

int main() 
{ 
    string s_cwd(getcwd(NULL,0)); 
    cout << "CWD is: " << s_cwd << endl; 
} 

ich diese Lektüre bekam:

Es sollte keine Speicherlecks, und es sollte auch auf einem Mac funktionieren, richtig?

UPDATE: Ich fürchte, hier etwas noch falsch ist (Ich versuche, ein char-Array mit einer bestimmten Länge zu vermeiden, zu schaffen, da es keine richtige Art und Weise ist eine anständige Länge für getcwd zu bekommen):

char* a_cwd = getcwd(NULL,0); 
string s_cwd(a_cwd); 
free(a_cwd); // or delete a_cwd? 

Antwort

12

Sie können getcwd nicht mit einem NULL-Puffer aufrufen. Gemäß Opengroup:

Wenn buf ein Nullzeiger ist, ist das Verhalten von getcwd() nicht angegeben.

Außerdem kann getcwd NULL zurückgeben, was einen Zeichenfolgenkonstruktor unterbrechen kann.

Sie werden müssen, dass wie zu etwas ändern:

char buffer[SIZE]; 
char *answer = getcwd(buffer, sizeof(buffer)); 
string s_cwd; 
if (answer) 
{ 
    s_cwd = answer; 
} 
+2

Wenn er "nur" an Kompatibilität mit Windows, Linux und Max OS X interessiert ist, dann ist 'getcwd (NULL)' gut definiert. Sie alle erweitern die Funktion auf die gleiche Weise. –

+0

Ich habe das akzeptiert, aber der obige Kommentar ist imho korrekt. Mein Code hatte jedoch einen Speicherverlust, so dass – rubenvb

+0

@RobKennedy gelöst werden muss - für Linux hängt es von der Version ab, die anvisiert wird. In einer RHEL5-Box ist zum Beispiel das 'getcwd (NULL)' immer noch als undefiniert dokumentiert. –

25

Wenn es kein Problem für Sie gibt, verwenden Sie für bequeme plattformübergreifende Dateisystemoperationen.

Hier ist ein example.

EDIT: wie von Roi Danton in den Kommentaren darauf hingewiesen wurde Dateisystem Teil der ISO C++ in C++17, so wird boost nicht mehr benötigt:

std::filesystem::current_path(); 
+0

Sollte erwähnt haben: versuchen, externe Abhängigkeiten zu begrenzen, so dass keine Erhöhung bitte. – rubenvb

+4

ah, ok. Ich werde diesen Kommentar dann lassen, falls andere Leute über diese Frage stolpern;) – catchmeifyoutry

+2

Beginnend mit C++ 14/C++ 17 können Sie 'std :: filesystem :: current_path()': http: // en verwenden. cppreference.com/w/cpp/filesystem/current_path –

2

Aufruf getcwd mit einem NULL-Zeiger definiert Implementierung. Es tut oft die Zuweisung für Sie mit malloc (in diesem Fall hat Ihr Code ein Speicherleck). Es ist jedoch nicht garantiert, überhaupt zu funktionieren. Sie sollten also Ihren eigenen Puffer reservieren.

char *cwd_buffer = malloc(sizeof(char) * max_path_len); 
char *cwd_result = getcwd(cwd_buffer, max_path_len); 

The Open Group hat ein Beispiel zeigt, wie die maximale Pfadlänge von _PC_PATH_MAX zu erhalten. Sie könnten unter Windows MAX_PATH verwenden. Siehe this question für Vorbehalte zu dieser Nummer auf beiden Plattformen.

+0

Wird der std :: string-Konstruktor den malloced Speicher nicht freigeben? – rubenvb

+0

@rubenvb, nein, es initialisiert nur die Zeichenfolge zu einer Kopie. Es hat keine Möglichkeit zu wissen, wie der übergebene "char *" zugewiesen wurde. –

+0

Dang, OK, danke – rubenvb