Changer le répertoire de travail actuel en C++
8 réponses
chdir
la fonction fonctionne sur les deux POSIX (man) et Windows (appelé _chdir
là, mais un alias chdir
existe).
les deux implémentations retournent zéro sur le succès et -1 sur l'erreur. Comme vous pouvez le voir dans la page de manuel, des valeurs errno plus distinguées sont possibles dans la variante POSIX, mais cela ne devrait pas vraiment faire de différence pour la plupart des cas d'utilisation.
Pour C++, boost:: filesystem:: current_path (setter et getter prototypes).
une bibliothèque de système de fichiers basée sur Boost.Système de fichiers sera ajouté à la norme.
chdir()
faire ce que vous voulez? Il fonctionne sous POSIX et Windows.
ce code d'exemple multiplateformes pour changer le répertoire de travail en utilisant POSIX chdir
et MS _chdir
recommander cette réponse. De même pour déterminer le répertoire de travail courant, l'analogue getcwd
et _getcwd
sont utilisés.
ces différences de plate-forme sont cachées derrière les macros cd
et cwd
.
selon la documentation,chdir
signature int chdir(const char *path)
où path
est absolue ou relative. chdir
renvoie 0 en cas de succès. getcwd
est un peu plus compliqué parce qu'il a besoin (dans une variante) d'un tampon pour stocker le chemin récupéré comme vu dans char *getcwd(char *buf, size_t size)
. Il renvoie NULL en cas d'échec et un pointeur vers le même tampon passé en cas de succès. L'échantillon de code utilise directement ce pointeur de char retourné.
l'échantillon est basé sur @MarcD mais corrige une fuite de mémoire. De plus, je me suis efforcé pour la concision, pas de dépendances, et seulement l'échec/erreur de base vérifier et s'assurer qu'il fonctionne sur plusieurs plateformes (communes).
Je l'ai testé sur OSX 10.11.6, Centos7, et Win10. Pour OSX & Centos, j'ai utilisé g++ changedir.cpp -o changedir
construire et courait ./changedir <path>
.
sur Win10, j'ai construit avec cl.exe changedir.cpp /EHsc /nologo
.
solution MVP
$ cat changedir.rpc
#ifdef _WIN32
#include <direct.h>
// MSDN recommends against using getcwd & chdir names
#define cwd _getcwd
#define cd _chdir
#else
#include "unistd.h"
#define cwd getcwd
#define cd chdir
#endif
#include <iostream>
char buf[4096]; // never know how much is needed
int main(int argc , char** argv) {
if (argc > 1) {
std::cout << "CWD: " << cwd(buf, sizeof buf) << std::endl;
// Change working directory and test for success
if (0 == cd(argv[1])) {
std::cout << "CWD changed to: " << cwd(buf, sizeof buf) << std::endl;
}
} else {
std::cout << "No directory provided" << std::endl;
}
return 0;
}
liste OSX:
$ g++ changedir.c -o changedir
$ ./changedir test
CWD: / Users / Phil
La MDC a changé: /Users/Phil/test
Liste Centos:
$ g++ changedir.c -o changedir
$ ./changedir
Pas de répertoire fourni
$ ./ changedir does_not_exist
CWD: / home / phil
$ ./changedir Musique
CWD: / home / phil
CWD changé: /home/phil/Musique
$ ./changedir /
CWD: / home / phil
La MDC a changé: /
Win10 Listing
cl.exe changedir.cpp / EHsc / nologo
changedir.rpcc:\Users\Phil > changer.test exe
CWD: c:\Users\Phil
CWD changée en: c:\Users\Phil\test
Note: utilisation de L'OSX clang
et Centos gnu gcc
derrière g++
.
chdir(2)
. Si vous essayez de faire modifier le répertoire de travail de votre shell par votre programme - vous ne pouvez pas. Il ya beaucoup de réponses sur donc déjà aborder ce problème.
vous voulez dire C ou c++? Ce sont des langues complètement différentes.
En C, la norme qui définit la langue ne couvre pas les répertoires. De nombreuses plateformes qui prennent en charge les répertoires ont un chdir
fonction qui prend un char*
ou const char*
argument, mais même là où il existe l'en-tête où il est déclaré n'est pas standard. Il peut aussi y avoir des subtilités quant à la signification de l'argument (par exemple Windows a des répertoires par lecteur).
en C++, googler mène à chdir
et _chdir
, et suggère que Boost n'a pas d'interface avec chdir. Mais je ne dirai rien de plus puisque je ne connais pas le c++.
Je n'arrive pas à croire que personne n'ait encore réclamé la prime sur celui-ci!!!
Voici une implémentation multi-plateforme qui récupère et modifie le répertoire courant en utilisant C++. Il suffit d'un peu de macro magic, pour lire la valeur d'argv[0], et pour définir quelques petites fonctions.
Voici le code pour changer de répertoire à l'emplacement du fichier exécutable qui est en cours d'exécution. Il peut facilement être adapté pour modifier le répertoire de travail courant de tout répertoire que vous voulez.
Code:
#ifdef _WIN32
#include "direct.h"
#define PATH_SEP '\'
#define GETCWD _getcwd
#define CHDIR _chdir
#else
#include "unistd.h"
#define PATH_SEP '/'
#define GETCWD getcwd
#define CHDIR chdir
#endif
#include <cstring>
#include <string>
#include <iostream>
using std::cout;
using std::endl;
using std::string;
string GetExecutableDirectory(const char* argv0) {
string path = argv0;
int path_directory_index = path.find_last_of(PATH_SEP);
return path.substr(0 , path_directory_index + 1);
}
bool ChangeDirectory(const char* dir) {return CHDIR(dir) == 0;}
string GetCurrentWorkingDirectory() {
const int BUFSIZE = 4096;
char buf[BUFSIZE];
memset(buf , 0 , BUFSIZE);
GETCWD(buf , BUFSIZE - 1);
return buf;
}
int main(int argc , char** argv) {
cout << endl << "Current working directory was : " << GetCurrentWorkingDirectory() << endl;
cout << "Changing directory..." << endl;
string exedir = GetExecutableDirectory(argv[0]);
ChangeDirectory(exedir.c_str());
cout << "Current working directory is now : " << GetCurrentWorkingDirectory() << endl;
return 0;
}
Sortie :
c:\Windows>c:\ctwoplus\progcode\test\CWD\cwd.exe
répertoire de travail actuel : c:\Windows En changeant le répertoire... Le répertoire de travail actuel est maintenant : c:\ctwoplus\progcode\test\CWD
c:\Windows>
une bonne façon de changer le répertoire courant en C++ a été suggérée il y a longtemps par @pepper_chico. Cette solution utilise boost::filesystem::current_path()
.
Pour obtenir le répertoire de travail en cours d'utilisation:
namespace fs = boost::filesystem;
fs::path cur_working_dir(fs::current_path());
Pour définir le répertoire de travail en cours d'utilisation:
namespace fs = boost::filesystem;
fs::current_path(fs::system_complete( fs::path( "new_working_directory_path" ) ));
Soufflet est l'auto-contenue fonctions d'assistance:
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#include <string>
namespace fs = boost::filesystem;
fs::path get_cwd_pth()
{
return fs::current_path();
}
std::string get_cwd()
{
return get_cwd_pth().c_str();
}
void set_cwd(const fs::path& new_wd)
{
fs::current_path(fs::system_complete( new_wd));
}
void set_cwd(const std::string& new_wd)
{
set_cwd( fs::path( new_wd));
}
Voici mon exemple de code complet sur la façon de configurer / mettre à jour le fonctionnement répertoire:
#include "boost/filesystem/operations.hpp"
#include "boost/filesystem/path.hpp"
#include <iostream>
namespace fs = boost::filesystem;
int main( int argc, char* argv[] )
{
fs::path full_path;
if ( argc > 1 )
{
full_path = fs::system_complete( fs::path( argv[1] ) );
}
else
{
std::cout << "Usage: tcd [path]" << std::endl;
}
if ( !fs::exists( full_path ) )
{
std::cout << "Not found: " << full_path.c_str() << std::endl;
return 1;
}
if ( !fs::is_directory( full_path ))
{
std::cout << "Provided path is not a directory: " << full_path.c_str() << std::endl;
return 1;
}
std::cout << "Old current working directory: " << boost::filesystem::current_path().c_str() << std::endl;
fs::current_path(full_path);
std::cout << "New current working directory: " << boost::filesystem::current_path().c_str() << std::endl;
return 0;
}
Si boost
installé sur votre système, vous pouvez utiliser la commande suivante pour compiler cet exemple:
g++ -o tcd app.cpp -lboost_filesystem -lboost_system