我想在当前目录(即可执行文件所在的位置)创建一个文件。
我的代码:
LPTSTR NPath = NULL;
DWORD a = GetCurrentDirectory(MAX_PATH,NPath);
HANDLE hNewFile = CreateFile(NPath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
我在使用GetCurrentDirectory()
时遇到了异常。
为什么会出现异常?
我想在当前目录(即可执行文件所在的位置)创建一个文件。
我的代码:
LPTSTR NPath = NULL;
DWORD a = GetCurrentDirectory(MAX_PATH,NPath);
HANDLE hNewFile = CreateFile(NPath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
我在使用GetCurrentDirectory()
时遇到了异常。
为什么会出现异常?
您可以通过更简洁的方法从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);
GetCurrentDirectory() 获取当前目录,也就是exe文件所在的位置,而这个exe是从哪里调用的。要获取exe文件的位置,可以使用GetModuleFileName(NULL ...)。如果你有exe文件的句柄,或者你可以从GetCommandLine()中推导出来。
正如Butterworth先生指出的那样,你不需要一个句柄。
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;
#include <direct.h>
// ...
char cwd[256];
getcwd(cwd, 256);
std::string cwd_str = std::string(cwd);
我想,定位当前目录最简单的方法是从命令行参数中切割它。
#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;
}
您可能知道每个程序都会将其可执行文件名作为第一个命令行参数。因此,您可以使用此功能。
$ ./prog
,argv [0]
将是 "./prog"
。 - Ciro García我的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。
如果您不想使用std,可以使用以下代码:
char * ExePath()
{
static char buffer[MAX_PATH] = { 0 };
GetModuleFileName( NULL, buffer, MAX_PATH );
char * LastSlash = strrchr(buffer, '\\');
if(LastSlash == NULL)
LastSlash = strrchr(buffer, '/');
buffer[LastSlash-buffer] = 0;
return buffer;
}
#include <iostream>
#if __cplusplus >= 201703L
// code for C++17 and later
#include <filesystem>
std::string cwd() { return std::filesystem::current_path(); }
#else
// code for earlier versions of c++
#include <unistd.h>
std::string cwd() {
char buffer[FILENAME_MAX];
if (getcwd(buffer, FILENAME_MAX) != nullptr) {
return {buffer};
}
return "";
}
#endif
int main() {
std::cout << cwd();
}
#include <iostream>
#include <unistd.h>
#include <limits.h>
// ONLY WORKING IN UNIX-LIKE SYSTEMS SUCH AS LINUX
int main() {
char cwd[PATH_MAX];
ssize_t size = readlink("/proc/self/cwd", cwd, sizeof(cwd));
if (size != -1) {
cwd[size] = '\0'; // Null-terminate the string
std::cout << "current working directory: " << cwd << std::endl;
} else {
std::cerr << "failed to read cwd" << std::endl;
}
return 0;
}
这个文档说...
[out] lpBuffer
指向接收当前目录字符串的缓冲区的指针。 这个以空字符结尾的字符串指定了当前目录的绝对路径。
要确定所需的缓冲区大小,请将此参数设置为NULL,并将nBufferLength参数设置为0。
你正在获取所需的缓冲区大小,而不是路径(NPath
为NULL),并且将nBufferLength设置为MAX_PATH
。
维基百科说...
C++11通过引入一个新的关键字来纠正这个问题,作为一个特殊的空指针常量:nullptr。它是nullptr_t类型,可以隐式转换和比较任何指针类型或指向成员的指针类型。它不能隐式转换或比较整数类型,除了bool。
没有办法区分一个 nullptr
和 NULL
(造成访问冲突异常)。
代码应该是这样的:
LPTSTR NewPath;
DWORD a = GetCurrentDirectory(0, NULL);
NewPath = new TCHAR[a];
GetCurrentDirectory(a, NPath);
HANDLE hNewFile = CreateFile(NewPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);