【发布时间】:2011-02-06 06:26:22
【问题描述】:
在我的编程语言的解释器中,我必须正确处理这些部分,以防调用 import 函数。然后我需要检查这样的文件是否在/libs 文件夹中(与我的可执行文件位于同一位置!),如果它不存在,我必须检查当前脚本的目录。
- 如何从 argv 获取可执行文件所在目录的确切路径?
-
从路径末尾删除文件的最佳方法是什么,例如:
C:/a/b/c/file.exe应该变成C:/a/b/c/
【问题讨论】:
在我的编程语言的解释器中,我必须正确处理这些部分,以防调用 import 函数。然后我需要检查这样的文件是否在/libs 文件夹中(与我的可执行文件位于同一位置!),如果它不存在,我必须检查当前脚本的目录。
从路径末尾删除文件的最佳方法是什么,例如:
C:/a/b/c/file.exe 应该变成C:/a/b/c/
【问题讨论】:
argv[0],但它是否包含完整路径或仅包含二进制文件的名称取决于平台以及您的进程是如何被调用的。strrchr 查找最后一个斜线并将其后面的字符替换为'\0'
代码示例:
// Duplicate the string so as not to trash the original
// You can skip this if you don't mind modifying the original data
// and the originald is writeable (i.e. no literal strings)
char *path = strdup(...);
char *last_slash = strrchr(path, '/');
if (last_slash)
{
#if PRESERVE_LAST_SLASH
*(last_slash + 1) = '\0';
#else
*last_slash = '\0';
#endif
}
【讨论】:
从字符串末尾向后扫描第一个 '/' 字符。
【讨论】:
如果 argv[0] 不包含整个路径,Linux(可能还有其他 *nix)上的一种不可移植方式是在 /proc/self/exe 上使用 readlink。
【讨论】:
不是最佳的,但工作正常:
int main(int argc, char **argv) {
using namespace std;
char buffer[MAXPATHLEN];
realpath(argv[0], buffer);
string fullpath = buffer;
fullpath = string(fullpath, 0, fullpath.rfind("/"));
cout << fullpath << endl;
}
对于相对路径,我使用的是 unix/linux 特定的 realpath()。对于windows你可以使用GetModuleFileName(NULL, buffer, MAXPATHLEN),当然分隔符不一样。
【讨论】:
如果您的环境在环境中具有 PWD 的等价物,您只需将 /$argv[0] 附加到它。
这可能会给您带来意想不到的东西,例如 /foo1/foo2/../foo3/ 但这没关系。这是一条有效的路径,可以通配。
【讨论】:
./my_prog 之外的任何方式执行。问题表明这是一个解释器。
对于 Windows(非便携式),请使用 ::GetModuleFileName() 和 ::PathRemoveFileSpec():
TCHAR sPath[MAX_PATH] = {0};
if(::GetModuleFileName(NULL, sPath, MAX_PATH))
::PathRemoveFileSpec(sPath))
// sPath is the executable path if the module is an exe
【讨论】: