Comment obtenir le répertoire courant dans un programme C?


163

Je crée un programme C où j'ai besoin d'obtenir le répertoire à partir duquel le programme est démarré. Ce programme est écrit pour les ordinateurs UNIX. J'ai regardé opendir()et telldir(), mais telldir()renvoie un off_t (long int), donc ça ne m'aide vraiment pas.

Comment puis-je obtenir le chemin actuel dans une chaîne (tableau de caractères)?

Réponses:


292

Avez-vous jeté un coup d'œil getcwd()?

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

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

11
Choisir le plus difficile des lentes, <errno.h> semble inutile, et le programme signale le succès même en cas d'échec via son statut de sortie. Sinon, un bel exemple.
— Jonathan Leffler

21
Oh, et est-il plus conventionnel d'utiliser printf (...) à la place de fprintf (stdout, ...)?
— Jonathan Leffler

19
@JonathanLeffler: Ce n'est pas la plus difficile des lentes. C'est: int main()devrait être int main(void).
— Keith Thompson

4
J'utiliserais PATH_MAX de limits.h, au lieu du nombre magique si ~ 4 Ko sur la pile n'est pas un problème.
— jacekmigacz

1
Toujours pas là, votre tampon devrait également accueillir l'octet de terminaison de chaîne / null, donc le bon est char cwd[PATH_MAX+1]. Ou si vous ne pouvez pas être dérangé par les tampons juste char *buf=getcwd(NULL,0);et quand vous avez terminé free(buf)(à partir de POSIX.1-2001)
— bliako

60

Recherchez dans la page de manuel getcwd.


7
@angad apprend à un homme à pêcher mais au moins lui montre le chemin vers le lac / la mer / l'océan :)
— MTK

3
les gens qui recommandent l'homme aux personnes qui essaient d'utiliser la méthode de recherche largement supérieure google sont déconnectés.
— gbtimmon

3
Extrait de code: man 3 getcwd. Blagues à part, ne soyez pas anarchoniste, cet article date de '08, les conventions SO étaient différentes.
— Kroltan

2
@gbtimmon google est un moteur de recherche, il n'est pas analogue à la page de manuel. Il va finalement pointer vers la page de manuel.
— Ajay Brahmakshatriya

24

Bien que la question soit étiquetée Unix, les gens peuvent également la visiter lorsque leur plate-forme cible est Windows, et la réponse pour Windows est la GetCurrentDirectory()fonction:

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

Ces réponses s'appliquent à la fois au code C et C ++.

Lien suggéré par l' utilisateur4581301 dans un commentaire à une autre question, et vérifié comme premier choix actuel avec une recherche Google "site: microsoft.com getcurrentdirectory".


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

3
Pourquoi n'utilisez-vous pas des macros prédéfinies pour détecter un système d'exploitation comme #if defined (_WIN32) || défini (_WIN64) || défini ( WINDOWS )
— HaseeB Mir

1

Notez qu'il getcwd(3)est également disponible dans la libc de Microsoft: getcwd (3) et fonctionne de la même manière que vous vous attendez.

Doit être lié à -loldnames(oldnames.lib, ce qui est fait automatiquement dans la plupart des cas), ou utiliser _getcwd(). La version sans préfixe n'est pas disponible sous Windows RT.


0

Pour obtenir le répertoire actuel (dans lequel vous exécutez votre programme cible), vous pouvez utiliser l'exemple de code suivant, qui fonctionne à la fois pour Visual Studio et Linux / MacOS (gcc / clang), à la fois C et 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;
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.