¿Cómo obtener el directorio actual en un programa en C?

162

Estoy haciendo un programa en C donde necesito obtener el directorio desde el que se inicia el programa. Este programa está escrito para computadoras UNIX. He estado mirando opendir()y telldir(), pero telldir()devuelve un off_t (long int), así que realmente no me ayuda.

¿Cómo puedo obtener la ruta actual en una cadena (matriz de caracteres)?

CharlesB
fuente

Respuestas:

291

¿Has echado un vistazo getcwd()?

#include <unistd.h>
char *getcwd(char *buf, size_t size);

Ejemplo simple:

#include <unistd.h>
#include <stdio.h>
#include <limits.h>

int main() {
   char cwd[PATH_MAX];
   if (getcwd(cwd, sizeof(cwd)) != NULL) {
       printf("Current working dir: %s\n", cwd);
   } else {
       perror("getcwd() error");
       return 1;
   }
   return 0;
}
Micrófono
fuente
11
Escogiendo las liendres más exigentes, <errno.h> parece innecesario, y el programa informa de éxito incluso en caso de falla a través de su estado de salida. De lo contrario, un buen ejemplo.
Jonathan Leffler
21
Ah, y ¿es más convencional usar printf (...) en lugar de fprintf (stdout, ...)?
Jonathan Leffler
19
@ JonathanLeffler: Esa no es la más delicada de las liendres. Esto es: int main()debería ser int main(void).
Keith Thompson
44
Usaría PATH_MAX desde los límites. H, en lugar del número mágico si ~ 4KB en la pila no es un problema.
jacekmigacz
1
Todavía no está allí, su búfer también debe acomodar el byte / nulo de terminación de cadena, por lo tanto, el correcto es char cwd[PATH_MAX+1]. O si no puede molestarse con los tampones solo char *buf=getcwd(NULL,0);y cuando haya terminado free(buf)(a partir de POSIX.1-2001)
bliako
60

Busque la página del manual para getcwd.

CAdaker
fuente
77
@angad enseña a un hombre a pescar, pero al menos muéstrale el camino hacia el lago / mar / océano :)
mtk
3
las personas que recomiendan el hombre a las personas que intentan utilizar el método de búsqueda muy superior de Google están fuera de contacto.
gbtimmon
3
Fragmento de código: man 3 getcwd. Bromas aparte, no seas anarquista, esta publicación es del '08, las convenciones SO eran diferentes.
Kroltan
2
@gbtimmon google es un motor de búsqueda, no es análogo a la página de manual. Eventualmente va a apuntar a la página del manual.
Ajay Brahmakshatriya
24

Aunque la pregunta está etiquetada como Unix, las personas también pueden visitarla cuando su plataforma de destino es Windows, y la respuesta para Windows es la GetCurrentDirectory()función:

DWORD WINAPI GetCurrentDirectory(
  _In_  DWORD  nBufferLength,
  _Out_ LPTSTR lpBuffer
);

Estas respuestas se aplican a los códigos C y C ++.

Enlace sugerido por el usuario 4581301 en un comentario a otra pregunta, y verificado como la mejor opción actual con un sitio de búsqueda de Google: microsoft.com getcurrentdirectory.

Jonathan Leffler
fuente
2
#include <stdio.h>  /* defines FILENAME_MAX */
//#define WINDOWS  /* uncomment this line to use it for windows.*/
#ifdef WINDOWS
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#include <unistd.h>
#define GetCurrentDir getcwd
#endif

int main(){
  char buff[FILENAME_MAX];
  GetCurrentDir( buff, FILENAME_MAX );
  printf("Current working dir: %s\n", buff);
  return 1;
}
Jevgenij Kononov
fuente
3
¿Por qué no utiliza macros pre_definidas para detectar sistemas operativos como #if defined (_WIN32) || definido (_WIN64) || definido ( VENTANAS )
HaseeB Mir
1

Tenga en cuenta que getcwd(3)también está disponible en la libc de Microsoft: getcwd (3) , y funciona de la misma manera que esperaría.

Debe vincularse con -loldnames(oldnames.lib, que se realiza automáticamente en la mayoría de los casos), o usar _getcwd(). La versión no prefijada no está disponible en Windows RT.

rvx
fuente
0

Para obtener el directorio actual (donde ejecuta su programa de destino), puede usar el siguiente código de ejemplo, que funciona tanto para Visual Studio como para Linux / MacOS (gcc / clang), tanto C como C ++:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if defined(_MSC_VER)
#include <direct.h>
#define getcwd _getcwd
#elif defined(__GNUC__)
#include <unistd.h>
#endif

int main() {
    char* buffer;

    if( (buffer=getcwd(NULL, 0)) == NULL) {
        perror("failed to get current directory\n");
    } else {
        printf("%s \nLength: %zu\n", buffer, strlen(buffer));
        free(buffer);
    }

    return 0;
}
HaxtraZ
fuente