Y a-t-il un équivalent C++ pour getcwd?

je vois C est getcwd via: homme 3 mdc

je soupçonne que C++ en a un similaire, qui pourrait me rendre un std:: string .

si oui, comment s'appelle-t-il, et Où puis-je trouver sa documentation?

Merci!

25
demandé sur anon 2010-02-04 23:56:43

8 réponses

Ok, je réponds même si vous avez déjà accepté une réponse.

une façon encore meilleure que d'envelopper l'appel getcwd serait d'utiliser boost:: filesystem, où vous obtenez un path objet de l' current_path() fonction. La bibliothèque du système de fichiers Boost vous permet de faire beaucoup d'autres choses utiles que vous auriez autrement besoin de faire beaucoup d'analyse de chaîne de caractères à faire, comme vérifier si les fichiers/répertoires existent, obtenir le chemin parent, faire des chemins complete etcetera. Check it out, il est portable aussi bien - qu'un grand nombre du parsing de chaîne de code que l'on utiliserait autrement ne sera probablement pas.

mise à Jour (2016): le système de fichiers a été publié en tant que spécification technique en 2015, basé sur Boost Filesystem v3. Cela signifie qu'il peut déjà être disponible avec votre compilateur (par exemple Visual Studio 2015). Pour moi, il semble aussi probable qu'il fera partie d'une future norme C++ (Je supposerais C++17, Mais je ne suis pas au courant de la statut.)

mise à Jour (2017):Bibliothèque du système de fichiers a été fusionné avec ISO C++ en C++17, pour

std::filesystem::current_path();
20
répondu villintehaspam 2017-10-04 20:20:37

std::string'constructeur peut prendre en toute sécurité une char* comme paramètre. Étonnamment, il y a un version de windows trop.

Edit: en fait c'est un peu plus compliqué:

std::string get_working_path()
{
   char temp[MAXPATHLEN];
   return ( getcwd(temp, MAXPATHLEN) ? std::string( temp ) : std::string("") );
}

la mémoire n'est pas un problème -- temp est un buffer basé sur la pile, et le constructeur std::string fait une copie. Vous pourriez probablement le faire en une seule fois, mais je ne pense pas que la norme garantirait cela.

à Propos de l'allocation de la mémoire, par POSIX:

la fonction getcwd () doit placer un chemin absolu du répertoire courant dans le tableau pointé par buf, et retourner buf. Le chemin d'accès copié pour le tableau contient pas de composants qui sont des liens symboliques. L'argument taille est la taille en octets du tableau de caractères pointé par l'argument buf. Si buf est un pointeur nul, le comportement de getcwd() n'est pas spécifié.

17
répondu Kornel Kisielewicz 2010-02-04 22:33:14

essayons de réécrire cet appel C simple comme C++:

std::string get_working_path()
{
    char temp [ PATH_MAX ];

    if ( getcwd(temp, PATH_MAX) != 0) 
        return std::string ( temp );

    int error = errno;

    switch ( error ) {
        // EINVAL can't happen - size argument > 0

        // PATH_MAX includes the terminating nul, 
        // so ERANGE should not be returned

        case EACCES:
            throw std::runtime_error("Access denied");

        case ENOMEM:
            // I'm not sure whether this can happen or not 
            throw std::runtime_error("Insufficient storage");

        default: {
            std::ostringstream str;
            str << "Unrecognised error" << error;
            throw std::runtime_error(str.str());
        }
    }
}

la chose est, quand vous enveloppez une fonction de bibliothèque dans une autre fonction vous devez supposer que toutes les fonctionnalités devraient être exposées, parce qu'une bibliothèque ne sait pas ce qui va l'appeler. Vous devez donc gérer les cas d'erreur plutôt que de simplement les avaler ou d'espérer qu'ils ne se produiront pas.

il est généralement préférable de laisser le code client appeler la fonction bibliothèque, et de traiter l'erreur à ce moment-là point - le code client ne se soucie probablement pas de savoir pourquoi l'erreur s'est produite, et ne doit donc traiter que le cas réussite/échec, plutôt que tous les codes d'erreur.

11
répondu Pete Kirkham 2013-11-09 14:56:17

vous aurez juste besoin d'écrire un petit papier.

std::string getcwd_string( void ) {
   char buff[PATH_MAX];
   getcwd( buff, PATH_MAX );
   std::string cwd( buff );
   return cwd;
}
5
répondu Brian Gianforcaro 2010-02-04 21:06:51

toutes les fonctions C sont aussi des fonctions c++. Si vous avez besoin d'un std::string, il suffit d'en créer un à partir de char* que getcwd obtient pour vous.

3
répondu Rob Kennedy 2010-02-04 20:59:18

j'ai utilisé getcwd() en C de la façon suivante:

char * cwd;
cwd = (char*) malloc( FILENAME_MAX * sizeof(char) );
getcwd(cwd,FILENAME_MAX);

Le fichier d'en-tête nécessaires est stdio.h. Quand j'utilise le compilateur C, ça marche parfaitement.

si je compile exactement le même code en utilisant C++ compiler, il signale le message d'erreur suivant:

identifier "getcwd" is undefined

Puis j'ai compris unistd.h et compilé avec le compilateur C++. Cette fois, tout fonctionne. Quand je suis revenu au compilateur C, ça marche toujours!

aussi longtemps Que vous incluez les deux stdio.h et unistd.h, le code ci-dessus fonctionne pour les compilateurs C et C++.

2
répondu Zhongming Qu 2013-10-30 14:56:37

j'ai aussi utilisé boost:: filesystem comme dit dans une autre réponse ci-dessus. Je voulais juste ajouter que, depuis l' current_path () la fonction ne renvoie pas une chaîne std::, Vous devez la convertir.

Voici ce que j'ai fait:

std::string cwd = boost::filesystem::current_path().generic_string();
1
répondu crecre 2017-06-15 16:24:59

Vous pouvez créer une nouvelle fonction, que je préférerais plutôt qu'un lien vers une bibliothèque comme boost(à moins que vous ne le soyez déjà).

 std::string getcwd()
 {
     char* buff;//automatically cleaned when it exits scope
     return std::string(getcwd(buff,255));
 }
-1
répondu Cody Serino 2017-07-07 18:21:58