Как получить текущий каталог?
Я делал это на С# и Delphi, но С++ злой. Целью является создание файла в текущем каталоге (где выполняется исполняемый файл).
Мой код:
LPTSTR NPath = NULL;
DWORD a = GetCurrentDirectory(MAX_PATH,NPath);
HANDLE hNewFile = CreateFile(NPath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
Я получаю исключение в GetCurrentDirectory().
Скажите, пожалуйста, почему я получаю исключение и как упростить его на С++?
Ответы
Ответ 1
Я бы порекомендовал прочитать книгу на С++, прежде чем идти дальше, так как было бы полезно получить более прочную основу. Ускоренный С++ от Koenig и Moo отлично.
Чтобы получить исполняемый путь, используйте GetModuleFileName:
char buffer[MAX_PATH];
GetModuleFileName( NULL, buffer, MAX_PATH );
Здесь функция С++, которая получает каталог без имени файла:
#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";
}
Ответ 2
GetCurrentDirectory
не выделяет пространство для результата, это для вас, чтобы сделать это.
TCHAR NPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH, NPath);
Кроме того, посмотрите, пожалуйста, на Boost.Filesystem, если вы хотите сделать это на С++.
Ответ 3
IMHO вот некоторые улучшения анонимного ответа.
#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( "\\/" ));
}
Ответ 4
Вы должны указать действительный буфер.
то есть:
TCHAR s[100];
DWORD a = GetCurrentDirectory(100, s);
Ответ 5
Пожалуйста, не забудьте инициализировать свои буферы, прежде чем использовать их. И так же важно, дайте пространству буферов строки для окончания null
TCHAR path[MAX_PATH+1] = L"";
DWORD len = GetCurrentDirectory(MAX_PATH, path);
Ссылка
Ответ 6
#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:)
Ответ 7
Не ясно, нужен ли текущий рабочий каталог или путь к каталогу, содержащему исполняемый файл.
Большинство ответов, кажется, отвечают последнему.
Но для первого и второй части вопроса о создании файла стандарт С++ 17 теперь включает библиотеку файловой системы, что значительно упрощает это:
#include <filesystem>
#include <iostream>
std::filesystem::path cwd = std::filesystem::current_path() / "filename.txt";
std::ofstream file(cwd.string());
file.close();
Это выбирает текущий рабочий каталог, добавляет имя файла к пути и создает пустой файл. Обратите внимание, что объект path заботится об обработке зависимого пути os, поэтому cwd.string() возвращает строку зависимого пути os. Neato.
Ответ 8
#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);
}
Ответ 9
Вы можете удалить имя файла из 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);
Надеюсь, что это поможет!
Ответ 10
GetCurrentDirectory() получает текущий каталог, из которого вызывается exe. Чтобы получить местоположение exe, используйте GetModuleFileName (NULL...). , если у вас есть дескриптор exe, или вы можете получить его из GetCommandLine(), если вы этого не сделаете.
Как указывает г-н Баттерворт, вам не нужна ручка.
Ответ 11
WCHAR path[MAX_PATH] = {0};
GetModuleFileName(NULL, path, MAX_PATH);
PathRemoveFileSpec(path);
Ответ 12
Почему никто не рассматривает использование этого простого кода?
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;
Ответ 13
Простой способ сделать это:
int main(int argc, char * argv[]){
std::cout << argv[0];
std::cin.get();
}
argv[]
- это в значительной степени массив, содержащий аргументы, с которыми вы запускали .exe, но первым всегда является путь к исполняемому файлу. Если я собираю это, консоль показывает: C:\Users\Ulisse\source\repos\altcmd\Debug\currentdir.exe
Ответ 14
Фрагменты кода из моего проекта CAE с средой разработки 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);
}
Просто используйте храм CA2CAEX или CA2AEX, который вызывает внутренний API :: MultiByteToWideChar или :: WideCharToMultiByte.
Ответ 15
Если вы используете библиотеку Poco, это один лайнер, и он должен работать на всех платформах, я думаю.
Poco::Path::current()
Ответ 16
Чтобы найти каталог, в котором находится ваш исполняемый файл, вы можете использовать:
TCHAR szFilePath[_MAX_PATH];
::GetModuleFileName(NULL, szFilePath, _MAX_PATH);
Ответ 17
String^ exePath = Application::ExecutablePath;<br>
MessageBox::Show(exePath);