2009-05-17 6 views
42

Я делал это на C# и Delphi, но C++ злой. Целью является создание файла в текущем каталоге (где выполняется исполняемый файл).Как получить текущий каталог?

Мой код:

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

я получаю исключение в GetCurrentDirectory().

Пожалуйста, скажите мне, почему я получаю исключение и как упростить его на C++?

+2

#include символ * getcwd (символ * ЬиЕ, size_t размера); http://stackoverflow.com/questions/298510/how-to-get-the-current-directory-in-ac-program – Anuswadh

+0

возможно дубликат [Как получить каталог, программа работает от?] (http://stackoverflow.com/questions/143174/how-do-i-get-the-directory-that-a-program-is-running-from) – user

+2

ВНИМАНИЕ: текущий каталог не всегда каталог, в котором находится exe. (например, c: \ users \ me> \ dir1 \ dir2 \ runme.exe здесь вы находитесь в каталоге c: \ users \ me и запускаете exe из \ dir1 \ dir2 \). – Mercury

ответ

97

Я бы рекомендовал прочитать книгу на C++, прежде чем идти дальше, так как было бы полезно получить более прочную основу. Accelerated C++ от Koenig и Moo отлично.

Чтобы получить путь к исполняемому использовать GetModuleFileName:

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

Вот функция C++, которая получает каталог без имени файла:

#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

NB, что вам может понадобиться использовать широкий символ, например буфер wchar_t [MAX_PATH]; в эти дни ... – rogerdpack

+2

Или 'GetModuleFileNameA' – Mikhail

+1

Чтобы повторить то, что сказал @Mikhail, вы бы использовали' GetModuleFileNameA' для кода, который использует многобайтовый набор символов и 'GetModuleFileNameW' для юникода. 'GetModuleFileName' (без' A' или 'W') на самом деле является псевдонимом для любого символа, установленного для вашего проекта, поэтому большинство методов Win32 API, которые используют строки, настроены. Поэтому, если у вас есть проект unicode, а ваши строки также являются unicode, вам нужно будет только вызвать 'GetModuleFileName'. То же самое относится, если ваш проект многобайтовый и использует многобайтовые строки. – RectangleEquals

30

GetCurrentDirectory не выделяет пространство для результата, это зависит от вас.

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

Кроме того, посмотрите на Boost.Filesystem библиотеку, если вы хотите сделать это C++ путь.

+0

Хмм, NPath указывает на другой каталог, как мне показать каталог, в который находится исполняемый файл? –

+6

Текущий каталог не совпадает с каталогом исполняемого файла, даже в C# и Delphi. Возможно, вы могли бы сделать свой вопрос яснее? – 2009-05-17 19:13:32

+0

Джон, это немного больше связано и не может просто ответить в комментарии. Возможно, вам следует следовать совету Нейла (оба они). – avakar

4

Вы должны предоставить действительный буферный заполнитель. что:

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

GetCurrentDirectory() возвращает текущий каталог, который где ех вызывается из. Чтобы получить местоположение exe, используйте GetModuleFileName (NULL ...). , если у вас есть дескриптор exe, или вы можете получить его из GetCommandLine(), если вы этого не сделаете.

Как указывает мистер Баттерворт, вам не нужна ручка.

+3

На самом деле вам не нужен реальный дескриптор - дескриптор NULL получает имя исполняемого файла с путём. – 2009-05-17 19:19:51

-1

Чтобы найти каталог, где исполняемый, вы можете использовать:

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

Пожалуйста, не забудьте инициализировать буферы то, прежде чем использовать их. И точно так же, как важно, дайте струнные буферные пространства для закончившейся нулевой

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

Reference

9

ИМХО вот некоторые улучшения 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

Это на самом деле другое. Вы не указываете путь к каталогу, вы указываете путь к файлу, включая файл. – 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

Вы можете удалить имя файла из GetModuleFileName() с более изящным способом:

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

Надеется, что это помогает!

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

фрагменты кода из моего проекта CAE с средой разработки юникода:

/// @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); 
} 

Просто используйте Templete CA2CAEX или CA2AEX который вызывает внутренний API :: MultiByteToWideChar или :: 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; 
} 

Мне не удалось правильно использовать GetModuleFileName. Я нашел эту работу очень хорошо. только что протестирован на Windows, еще не попробовать Linux :)

1

Почему никто здесь не рассматривает этот простой код?

TCHAR szDir[MAX_PATH] = { 0 }; 

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

или даже проще

TCHAR szDir[MAX_PATH] = { 0 }; 
TCHAR* szEnd = nullptr; 
GetModuleFileName(NULL, szDir, MAX_PATH); 
szEnd = _tcsrchr(szDir, '\\'); 
*szEnd = 0; 
Смежные вопросы