2010-05-19 13 views
15

Necesito una forma de plataforma cruzada para obtener el directorio de trabajo actual (sí, getcwd hace lo que quiero). Pensé que esto podría hacer el truco:¿Qué es una forma de plataforma cruzada para obtener el directorio actual?

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

llegué esta lectura:

No debe haber fugas de memoria, y se debería funcionar en una Mac también, ¿correcto?

ACTUALIZACIÓN: Me temo que todavía le queda algo mal aquí (estoy tratando de evitar la creación de una matriz de caracteres con una longitud determinada, ya que no hay manera adecuada para obtener una longitud decente para getcwd):

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

Respuesta

12

No puede llamar al getcwd con un búfer NULL. Según Opengroup:

Si buf es un puntero nulo, el comportamiento de getcwd() no está especificado.

Además, getcwd puede devolver NULL, lo que puede romper un constructor de cadena.

Tendrá que cambiar eso a algo como:

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

Si solo está "interesado" en la compatibilidad con Windows, Linux y Max OS X, entonces 'getcwd (NULL)' está bien definido. Todos extienden la función de la misma manera. –

+0

Acepté esto, pero el comentario anterior es absolutamente correcto. Mi código tenía una pérdida de memoria, por lo que necesita resolver – rubenvb

+0

@RobKennedy - para Linux, depende de la versión que se trate. Por ejemplo, en una casilla RHEL5, 'getcwd (NULL)' todavía se documenta como indefinido. –

25

Si no tiene ningún problema para incluirlo, use boost filesystem para las operaciones convenientes del sistema de archivos multiplataforma.

boost::filesystem::path full_path(boost::filesystem::current_path()); 

Aquí hay un example.

EDIT: como ha señalado Roi Danton en los comentarios, sistema de ficheros se convirtió en parte de la ISO C++ in C++17, por lo impulso ya no se necesita:

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

debería haber mencionado: tratar de limitar las dependencias externas, por lo que no Boost favor. – rubenvb

+4

ah, vale. Dejaré este comentario entonces en caso de que otras personas tropiecen con esta pregunta;) – catchmeifyoutry

+2

A partir de C++ 14/C++ 17, puede usar 'std :: filesystem :: current_path()': http: // en. cppreference.com/w/cpp/filesystem/current_path –

2

Calling getcwd con un puntero NULL se define la aplicación. A menudo hace la asignación para usted con malloc (en cuyo caso su código tiene una pérdida de memoria). Sin embargo, no se garantiza que funcione en absoluto. Entonces deberías asignar tu propio buffer.

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

El Grupo abierto tiene un ejemplo que muestra cómo obtener la longitud de ruta máxima de _PC_PATH_MAX. Podría considerar usar MAX_PATH en Windows. Vea this question para advertencias a este número en ambas plataformas.

+0

¿El constructor std :: string no liberará la memoria malloc'ed? – rubenvb

+0

@rubenvb, no, solo inicializa la cadena a una copia. No tiene forma de saber cómo se asignó el pasado en 'char *'. –

+0

Dang, OK, gracias – rubenvb

Cuestiones relacionadas