如何从完整路径中提取文件名

3

在一个C程序中,我有一个字符串表示的文件路径(具体来说是存储在argv[0]中的exe名称)。我想提取文件名并且舍弃目录路径,使用MS Visual Studio 2005。是否有任何内置函数可以实现这一功能?

5个回答

5

供参考,这是我实现的代码,据说可以在Win/Unix上兼容:

    char *pfile;
    pfile = argv[0] + strlen(argv[0]);
    for (; pfile > argv[0]; pfile--)
    {
        if ((*pfile == '\\') || (*pfile == '/'))
        {
            pfile++;
            break;
        }
    }

4

其实不用,只需定位路径中最后一个反斜杠即可。反斜杠后面的所有内容都是文件名,如果没有则表示路径指定了目录名。

// Returns filename portion of the given path
// Returns empty string if path is directory
char *GetFileName(const char *path)
{
    char *filename = strrchr(path, '\\');
    if (filename == NULL)
        filename = path;
    else
        filename++;
    return filename;
}

谢谢,@Jonathan。是的,那是显而易见的方法。我想可能有一个现成的函数可以帮我省去编码工作。 - ysap
这里应该有更多的 const - unwind
这里是我想要避免的问题 - 这段代码只适用于Windows。在Unix上不起作用,因为斜杠应该是反斜杠。无论如何,感谢提供代码。 - ysap

2
如果您需要从libc中获取一个函数:
#include <unistd.h>

char * basename (const char *fname);

谢谢,发现得很好。尽管根据man手册,在存在尾随斜杠时,POSIX版本比GNU版本不太合理。这个函数是否兼容Windows(即,是否受MSVC支持,并且是否识别反斜杠)? - ysap
是的,我相信文档说它将正斜杠和反斜杠视为分隔符。 - sjbx
当我们使用GNU时,glibc也定义并初始化了program_invocation_short_name变量。 - ysap


1
这是一个简化版:
char *p, *s = args[0]; // or any source pathname
...
p = strchr(s, '\\'); // find the 1st occurence of '\\' or '/'
// if found repeat the process (if not, s already has the string)
while(p) {
  s = ++p; // shift forward s first, right after '\\' or '/'
  p = strchr(p, '\\'); // let p do the search again
}
// s now point to filename.ext
...

注意:对于 _TCHAR,请使用 _tcschr 而不是 strchr strchr 的作用类似于:while((*p) && (*p != '\\')) p++; 如果未找到 chr,则会返回安全带 NULL。 因此,如果您真的不想依赖另一个库,可以使用这个方法。
char *p, *s = args[0];
...
p = s; // assign to s to p
while(*p && (*p != '\\')) p++;
while(*p) { // here we have to peek at char value
  s = ++p;
  while (*p && (*p != '\\')) p++;
}
// s now point to filename.ext
...

任何比这更低的级别,使用asm

谢谢。那是很久以前的事了......你的代码可能在Windows上运行,但在Unix上会失败。请参考其他答案。 - ysap

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接