Подтвердить что ты не робот

Как получить текущий каталог?

Я делал это на С# и 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().

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

4b9b3361

Ответ 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);