Como obter o diretório atual em um programa C?

162

Estou criando um programa em C onde preciso obter o diretório em que o programa é iniciado. Este programa foi escrito para computadores UNIX. Eu estive olhando opendir()e telldir(), mas telldir()retorna um off_t (long int), então isso realmente não me ajuda.

Como posso obter o caminho atual em uma string (matriz de caracteres)?

CharlesB
fonte

Respostas:

291

Você já deu uma olhada getcwd()?

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

Exemplo simples:

#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;
}
Microfone
fonte
11
Escolher o nits mais exigente, <errno.h> parece desnecessário, e o programa relata sucesso mesmo em caso de falha por meio do status de saída. Caso contrário, um bom exemplo.
Jonathan Leffler
21
Ah, e é mais convencional usar printf (...) no lugar de fprintf (stdout, ...)?
Jonathan Leffler
19
@ JonathanLeffler: Essa não é a mais exigente das lêndeas. Isto é: int main()deveria ser int main(void).
Keith Thompson
4
Eu usaria PATH_MAX de limits.h, em vez de número mágico, se ~ 4KB na pilha não for um problema.
precisa saber é o seguinte
1
Ainda não existe, seu buffer também deve acomodar o byte de terminação de seqüência de caracteres / nulo, portanto o correto é char cwd[PATH_MAX+1]. Ou se você não posso ser incomodado com buffers apenas char *buf=getcwd(NULL,0);e quando você está feito free(buf)(a partir de POSIX.1-2001)
bliako
60

Procure a página de manual getcwd.

CAdaker
fonte
7
@angad ensinar um homem a pescar, mas pelo menos mostrar-lhe caminho para o lago / mar / oceano :)
mtk
3
as pessoas que recomendam o homem para as pessoas que tentam usar o método de pesquisa amplamente superior do google estão fora de contato.
Gbtimmon 22/02
3
Trecho de código: man 3 getcwd. Brincadeiras à parte, não seja anarconista, este post é de 08, então as convenções eram diferentes.
Kroltan
2
@gbtimmon O google é um mecanismo de pesquisa, não é análogo à página de manual. Eventualmente, ele apontará para a página do manual.
Ajay Brahmakshatriya
24

Embora a pergunta esteja marcada como Unix, as pessoas também a visitam quando a plataforma de destino é o Windows, e a resposta para o Windows é a GetCurrentDirectory()função:

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

Essas respostas se aplicam aos códigos C e C ++.

Link sugerido pelo usuário4581301 em um comentário para outra pergunta e verificado como a principal opção atual com uma pesquisa no Google 'site: microsoft.com getcurrentdirectory'.

Jonathan Leffler
fonte
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
fonte
3
Por que você não usa macros predefinidas para detectar o SO como #if defined (_WIN32) || definido (_WIN64) || definido ( WINDOWS )
HaseeB Mir
1

Observe que getcwd(3)também está disponível na libc: getcwd (3) da Microsoft e funciona da mesma maneira que você esperaria.

É necessário vincular com -loldnames(oldnames.lib, que é feito automaticamente na maioria dos casos) ou usar _getcwd(). A versão não corrigida não está disponível no Windows RT.

rvx
fonte
0

Para obter o diretório atual (onde você executa seu programa de destino), você pode usar o seguinte código de exemplo, que funciona tanto para o Visual Studio quanto para o Linux / MacOS (gcc / clang), C e 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
fonte