如何获得当前目录?

时间:2009-05-17 19:05:38

标签: c++ windows

我一直在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 ++中轻松实现?

19 个答案:

答案 0 :(得分:110)

我建议您在继续学习之前阅读一本关于C ++的书,因为这样做有助于获得更稳固的基础。 Koenig和Moo的Accelerated C++非常出色。

要获取可执行路径,请使用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";
}

答案 1 :(得分:35)

GetCurrentDirectory没有为结果分配空间,由你来做。

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

另外,如果您想以C ++方式执行此操作,请查看Boost.Filesystem库。

答案 2 :(得分:11)

恕我直言,这是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( "\\/" ));
}

答案 3 :(得分:4)

您应该提供有效的缓冲区占位符。 那就是:

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

答案 4 :(得分:4)

问题尚不清楚,是需要当前工作目录还是包含可执行文件的目录路径。

大多数答案似乎都能回答后者。

但是对于前者以及创建文件问题的第二部分,C ++ 17标准现在合并了文件系统库,从而大大简化了此过程:

#include <filesystem>
#include <iostream>

std::filesystem::path cwd = std::filesystem::current_path() / "filename.txt";
std::ofstream file(cwd.string());
file.close();

这将获取当前工作目录,将文件名添加到路径并创建一个空文件。请注意,路径对象负责os依赖的路径处理,因此cwd.string()返回os依赖的路径字符串。尼阿托。

答案 5 :(得分:4)

#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 :)

答案 6 :(得分:4)

在使用之前,请不要忘记将缓冲区初始化为某些内容。同样重要的是,为结束null提供字符串缓冲区空间

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

Reference

答案 7 :(得分: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);

希望它有所帮助!

答案 8 :(得分:3)

#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 :(得分:2)

WCHAR path[MAX_PATH] = {0};
GetModuleFileName(NULL, path, MAX_PATH);
PathRemoveFileSpec(path);

答案 10 :(得分:2)

GetCurrentDirectory()获取当前目录,该目录是从调用exe 的地方。要获取exe的位置,请使用GetModuleFileName(NULL ...)。 如果你有exe的句柄,或者你可以从GetCommandLine()派生它,如果你没有。

正如巴特沃思先生指出的那样,你不需要手柄。

答案 11 :(得分: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;

答案 12 :(得分:1)

一个简单的方法是:

int main(int argc, char * argv[]){
    std::cout << argv[0]; 
    std::cin.get();
}

argv[]几乎是一个数组,其中包含运行.exe所使用的参数,但第一个始终是可执行文件的路径。如果我进行构建,控制台将显示: C:\Users\Ulisse\source\repos\altcmd\Debug\currentdir.exe

答案 13 :(得分:1)

我想,找到当前目录的最简单方法是从命令行args剪切它。

#include <string>
#include <iostream>

int main(int argc, char* argv[])
{
  std::string cur_dir(argv[0]);
  int pos = cur_dir.find_last_of("/\\");

  std::cout << "path: " << cur_dir.substr(0, pos) << std::endl;
  std::cout << "file: " << cur_dir.substr(pos+1) << std::endl;
  return 0;
}

您可能知道每个程序都将其可执行文件名作为第一个命令行参数。所以您可以使用它。

答案 14 :(得分:0)

使用unicode开发环境从我的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);
}

只需使用模板 CA2CAEX CA2AEX 调用内部API :: MultiByteToWideChar :: WideCharToMultiByte

答案 15 :(得分:0)

如果您使用的是Poco库,那么它是一个衬板,它应该可以在我认为的所有平台上工作。

Poco::Path::current()

答案 16 :(得分:-1)

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

答案 17 :(得分:-1)

要查找可执行文件所在的目录,可以使用:

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

答案 18 :(得分:-2)

我很惊讶没有人推荐这种简单的方法 如果您在 Windows 上,您可以执行此操作,知道 mac 和 linux 上列出目录的命令是什么,但您可以将系统命令更改为该命令

#include <cstdlib>
#include <fstream>
#include <string>
#include <string.h>
std::string dirname;

int results=system("cd >> dir.txt");
ifstream cwd("dir.txt");
while(getline(cwd,dirname)){
 std::cout<<dirname<<std::endl;
}
<块引用>

然后你可以删除dir.txt,如果你愿意

remove("dir.txt")