2009-05-17 26 views
42

He estado haciendo esto en C# y Delphi, pero C++ es malo. El propósito es crear un archivo en el directorio actual (donde se ejecuta el ejecutable).¿Cómo obtener el directorio actual?

Mi código:

LPTSTR NPath = NULL; 
DWORD a = GetCurrentDirectory(MAX_PATH,NPath); 
HANDLE hNewFile = CreateFile(NPath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); 

llego a excepción GetCurrentDirectory().

Por favor dígame por qué recibo una excepción y cómo puedo hacerla más fácil en C++?

+2

# include char * getcwd (char * buf, size_t tamaño); http://stackoverflow.com/questions/298510/how-to-get-the-current-directory-in-ac-program – Anuswadh

+0

posible duplicado de [¿Cómo consigo el directorio que un programa es corriendo desde?] (http://stackoverflow.com/questions/143174/how-do-i-get-the-directory-that-a-program-is-running-from) – user

+2

NOTA: el directorio actual no es siempre el directorio en el que se encuentra el exe. (por ejemplo, c: \ users \ me> \ dir1 \ dir2 \ runme.exe aquí se encuentra en c: \ users \ me y ejecuta exe desde \ dir1 \ dir2 \). – Mercury

Respuesta

97

Recomendaría leer un libro en C++ antes de seguir adelante, ya que sería útil tener una base más firme. Accelerated C++ por Koenig and Moo es excelente.

para obtener la ruta ejecutable utilizar GetModuleFileName:

char buffer[MAX_PATH]; 
GetModuleFileName(NULL, buffer, MAX_PATH); 

Aquí es una función de C++ que recibe el directorio sin el nombre del archivo:

#include <windows.h> 
#include <string> 
#include <iostream> 
using namespace std;; 

string ExePath() { 
    char buffer[MAX_PATH]; 
    GetModuleFileName(NULL, buffer, MAX_PATH); 
    string::size_type pos = string(buffer).find_last_of("\\/"); 
    return string(buffer).substr(0, pos); 
} 

int main() { 
    cout << "my directory is " << ExePath() << "\n"; 
} 
+4

Nota: es posible que necesite usar un carácter amplio, como el buffer wchar_t [MAX_PATH]; estos días ... – rogerdpack

+2

O 'GetModuleFileNameA' – Mikhail

+1

Para reiterar lo que dijo @Mikhail, usarías' GetModuleFileNameA' para el código que utiliza un conjunto de caracteres de múltiples bytes, y 'GetModuleFileNameW' para unicode. 'GetModuleFileName' (sin el' A' o 'W') es en realidad un alias para cualquier conjunto de caracteres que su proyecto esté configurado para usar, que es como la mayoría de los métodos de API Win32 que utilizan cadenas están configurados. Entonces, si tienes un proyecto Unicode, y tus cadenas también son unicode, entonces solo tendrías que llamar a 'GetModuleFileName'. Lo mismo se aplica si su proyecto es multibyte y utiliza cadenas de múltiples bytes. – RectangleEquals

30

GetCurrentDirectory no asigna espacio para el resultado, depende de usted hacer eso.

TCHAR NPath[MAX_PATH]; 
GetCurrentDirectory(MAX_PATH, NPath); 

También, echar un vistazo a Boost.Filesystem biblioteca si desea hacerlo de esta manera el C++.

+0

Hmm, NPath apunta a otro directorio, ¿cómo hago que muestre el directorio donde se coloca el ejecutable? –

+6

El directorio actual no es el mismo que el directorio del ejecutable, incluso en C# y Delphi. ¿Quizás podrías aclarar tu pregunta? –

+0

John, eso es un poco más complicado y no se puede responder simplemente en un comentario. Quizás deberías seguir el consejo de Neil (ambos). – avakar

4

debería proporcionar un marcador de posición tampón válido. que es:

TCHAR s[100]; 
DWORD a = GetCurrentDirectory(100, s); 
2

GetCurrentDirectory() Obtiene el directorio actual, que es donde el exe se invoca desde . Para obtener la ubicación del exe, use GetModuleFileName (NULL ...). si tiene el control para el exe, o puede derivarlo de GetCommandLine() si no lo hace.

Como señala el Sr. Butterworth, no necesita un asa.

+3

En realidad, no necesita un identificador real: un identificador NULL obtiene el nombre del archivo ejecutable, con la ruta. –

-1

Para encontrar el directorio donde el ejecutable es, puede utilizar:

TCHAR szFilePath[_MAX_PATH]; 
::GetModuleFileName(NULL, szFilePath, _MAX_PATH); 
3

Por favor, no se olvide de inicializar las memorias intermedias de algo antes de utilizarlos. Y lo más importante, darle su espacio de buffers de cadena para la terminación nula

TCHAR path[MAX_PATH+1] = L""; 
DWORD len = GetCurrentDirectory(MAX_PATH, path); 

Reference

9

mi humilde opinión, aquí hay algunas mejoras en anon's answer.

#include <windows.h> 
#include <string> 
#include <iostream> 

std::string GetExeFileName() 
{ 
    char buffer[MAX_PATH]; 
    GetModuleFileName(NULL, buffer, MAX_PATH); 
    return std::string(buffer); 
} 

std::string GetExePath() 
{ 
    std::string f = GetExeFileName(); 
    return f.substr(0, f.find_last_of("\\/")); 
} 
+0

Esto es realmente diferente. NO proporciona la ruta del directorio, proporciona la ruta del archivo, incluido el archivo. – dyesdyes

1
WCHAR path[MAX_PATH] = {0}; 
GetModuleFileName(NULL, path, MAX_PATH); 
PathRemoveFileSpec(path); 
1
#include <windows.h> 
using namespace std; 

// The directory path returned by native GetCurrentDirectory() no end backslash 
string getCurrentDirectoryOnWindows() 
{ 
    const unsigned long maxDir = 260; 
    char currentDir[maxDir]; 
    GetCurrentDirectory(maxDir, currentDir); 
    return string(currentDir); 
} 
3

Se puede quitar el nombre de archivo con GetModuleFileName() forma más elegante:

TCHAR fullPath[MAX_PATH]; 
TCHAR driveLetter[3]; 
TCHAR directory[MAX_PATH]; 
TCHAR FinalPath[MAX_PATH]; 
GetModuleFileName(NULL, fullPath, MAX_PATH); 
_splitpath(fullPath, driveLetter, directory, NULL, NULL); 
sprintf(FinalPath, "%s%s",driveLetter, directory); 

espero que ayude!

-3
String^ exePath = Application::ExecutablePath;<br> 
MessageBox::Show(exePath); 
0

Los fragmentos de código de mi proyecto CAE con el entorno de desarrollo Unicode:

/// @brief Gets current module file path. 
std::string getModuleFilePath() { 
    TCHAR buffer[MAX_PATH]; 
    GetModuleFileName(NULL, buffer, MAX_PATH); 
    CT2CA pszPath(buffer); 
    std::string path(pszPath); 
    std::string::size_type pos = path.find_last_of("\\/"); 
    return path.substr(0, pos); 
} 

sólo tiene que utilizar el templete CA2CAEX o CA2AEX que llama a la API interna :: MultiByteToWideChar o :: WideCharToMultiByte.

2
#include <iostream>  
#include <stdio.h> 
#include <dirent.h> 

std::string current_working_directory() 
{ 
    char* cwd = _getcwd(0, 0) ; // **** microsoft specific **** 
    std::string working_directory(cwd) ; 
    std::free(cwd) ; 
    return working_directory ; 
} 

int main(){ 
    std::cout << "i am now in " << current_working_directory() << endl; 
} 

No pude usar GetModuleFileName correctamente. Encontré este trabajo muy bien. acaba de probar en Windows, todavía no lo intente en Linux :)

1

¿Por qué nadie aquí considera utilizar este código simple?

TCHAR szDir[MAX_PATH] = { 0 }; 

GetModuleFileName(NULL, szDir, MAX_PATH); 
szDir[std::string(szDir).find_last_of("\\/")] = 0; 

o incluso más simple

TCHAR szDir[MAX_PATH] = { 0 }; 
TCHAR* szEnd = nullptr; 
GetModuleFileName(NULL, szDir, MAX_PATH); 
szEnd = _tcsrchr(szDir, '\\'); 
*szEnd = 0; 
Cuestiones relacionadas