c++ - hora - formato fecha c
Cambiar el directorio de trabajo actual en C++ (8)
¿Cómo puedo cambiar mi directorio de trabajo actual en C ++ de una manera independiente de la plataforma?
Encontré el archivo de encabezado direct.h
, que es compatible con Windows, y el unistd.h
, que es compatible con UNIX / POSIX.
¡No puedo creer que nadie haya reclamado la recompensa de este todavía!
Aquí hay una implementación multiplataforma que obtiene y cambia el directorio de trabajo actual usando C ++. Todo lo que se necesita es un poco de macro magia, leer el valor de argv [0] y definir algunas funciones pequeñas.
Aquí está el código para cambiar directorios a la ubicación del archivo ejecutable que se está ejecutando actualmente. Se puede adaptar fácilmente para cambiar el directorio de trabajo actual a cualquier directorio que desee.
Código:
#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;
}
Salida:
c: / Windows> c: / ctwoplus / progcode / test / CWD / cwd.exe
El directorio de trabajo actual era: c: / Windows Cambio de directorio ... El directorio de trabajo actual ahora es: c: / ctwoplus / progcode / test / CWD
c: / Windows>
¿ chdir()
hace lo que quieres? Funciona tanto con POSIX como con Windows.
¿Quisiste decir C o C ++? Son idiomas completamente diferentes.
En C, el estándar que define el idioma no cubre directorios. Muchas plataformas que admiten directorios tienen una función chdir
que toma un argumento char*
o const char*
, pero incluso donde existe el encabezado donde se declara no es estándar. También puede haber sutilezas en cuanto a lo que significa el argumento (por ejemplo, Windows tiene directorios por unidad).
En C ++, Google conduce a chdir
y _chdir
, y sugiere que Boost no tiene una interfaz para chdir. Pero no comentaré más ya que no conozco C ++.
Este código de muestra multiplataforma para cambiar el directorio de trabajo utilizando POSIX chdir
y MS _chdir
como se recomienda en esta respuesta . Del mismo modo, para determinar el directorio de trabajo actual, se utilizan los _getcwd
getcwd
y _getcwd
análogos.
Estas diferencias de plataforma están ocultas detrás de las macros cd
y cwd
.
Según la documentación, la firma de int chdir(const char *path)
es int chdir(const char *path)
donde la path
es absoluta o relativa. chdir
devolverá 0 en caso de éxito. getcwd
es un poco más complicado porque necesita (en una variante) un búfer para almacenar la ruta de acceso como se ve en char *getcwd(char *buf, size_t size)
. Devuelve NULL en caso de error y un puntero al mismo buffer pasado en caso de éxito. El ejemplo de código hace uso de este puntero de char devuelto directamente.
La muestra se basa en @ MarcD pero corrige una fuga de memoria. Además, procuré la concisión, sin dependencias, y solo la comprobación básica de errores / errores, así como garantizar que funciona en múltiples plataformas (comunes).
Lo probé en OSX 10.11.6, Centos7 y Win10. Para OSX y Centos, utilicé g++ changedir.cpp -o changedir
para compilar y ejecutar como ./changedir <path>
.
En Win10, construí con cl.exe changedir.cpp /EHsc /nologo
.
Solución MVP
$ cat changedir.cpp
#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;
}
Listado de OSX:
$ g ++ changedir.c -o changedir
Prueba $ ./changedir
CWD: / Usuarios / Phil
CWD cambió a: / Users / Phil / testing
Listado de Centos:
$ g ++ changedir.c -o changedir
$ ./changedir
No se proporcionó directorio
$ ./changedir does_not_exist
CWD: / home / phil
$ ./changedir Música
CWD: / home / phil
CWD cambió a: / home / phil / Music
$ ./changedir /
CWD: / home / phil
CWD cambió a: /
Listado de Win10
cl.exe changedir.cpp / EHsc / nologo
changedir.cppc: / Users / Phil> prueba de changedir.exe
CWD: c: / Users / Phil
CWD cambió a: c: / Users / Phil / test
Nota: OSX usa clang
y Centos gnu gcc
detrás de g++
.
La buena forma de plataforma cruzada para cambiar el directorio actual en C ++ fue sugerida hace mucho tiempo por @pepper_chico. Esta solución usa boost::filesystem::current_path()
.
Para obtener el uso actual del directorio de trabajo:
namespace fs = boost::filesystem;
fs::path cur_working_dir(fs::current_path());
Para establecer el uso del directorio de trabajo actual:
namespace fs = boost::filesystem;
fs::current_path(fs::system_complete( fs::path( "new_working_directory_path" ) ));
Bellow es las funciones autónomas de ayudante:
#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));
}
Aquí está mi completo ejemplo de código sobre cómo establecer / obtener el directorio de trabajo actual:
#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 el boost
instalado en su sistema puede usar el siguiente comando para compilar esta muestra:
g++ -o tcd app.cpp -lboost_filesystem -lboost_system
La función chdir
funciona tanto en POSIX (página de manpage ) como en Windows (llamada _chdir
allí pero existe un alias chdir
).
Ambas implementaciones devuelven cero en caso de éxito y -1 en error. Como puede ver en la página de manual, son posibles valores de errno más distinguidos en la variante POSIX, pero eso no debería marcar la diferencia para la mayoría de los casos de uso.
Para C ++, boost::filesystem::current_path (setter y getter prototypes).
Se agregará una biblioteca de sistema de archivos basada en Boost.Filesystem al estándar .
Quieres chdir(2)
. Si intenta que su programa cambie el directorio de trabajo de su caparazón, no puede. Hay muchas respuestas sobre SO que ya abordan ese problema.