获取文件的绝对路径

57

如何在Unix上使用C语言将相对路径转换为绝对路径? 有没有方便的系统函数可以使用?

在Windows上有一个GetFullPathName函数可以完成此任务,但我没有找到类似的Unix函数...

5个回答

71

使用 realpath() 函数。

realpath() 函数将从指向 file_name 的路径名派生出绝对路径名,该绝对路径名指定了相同的文件,其解析不涉及 '.', '..' 或符号链接。生成的路径名将作为以空字符结尾的字符串存储在由 resolved_name 指向的缓冲区中,最长不超过 {PATH_MAX} 字节。

如果 resolved_name 是空指针,则 realpath() 的行为是实现定义的。


以下示例为 symlinkpath 参数标识的文件生成绝对路径名,并将其存储在 actualpath 数组中。

#include <stdlib.h>
...
char *symlinkpath = "/tmp/symlink/file";
char actualpath [PATH_MAX+1];
char *ptr;


ptr = realpath(symlinkpath, actualpath);

14
“加一”并非必要,但也没有坏处。 - Jonathan Leffler
5
在Windows上,GetFullPathName也适用于不存在的文件。而realpath则要求路径存在。当你想创建一个路径或文件时,这种情况有点糟糕。 - Joakim
5
实际路径包含绝对路径,但 ptr 包含什么? - Sam Thomas
3
从 POSIX limits.h 的原理中可以得知,不需要使用 @EML +1。"IEEE PASC 解释1003.1 #15解决了标准中路径名定义和 {PATH_MAX} 描述的不一致性,允许应用程序开发人员分配 {PATH_MAX} 或 {PATH_MAX} + 1 字节。通过将空字符包含在 {PATH_MAX} 定义中进行更正,已经消除了这种不一致性。通过这个更改,之前分配了 {PATH_MAX} 字节的应用程序将继续成功运行。" - osvein
1
@osvein PATH_MAX 不需要存在:在特定的实现中,如果对应值等于或大于规定的最小值,但是该值可能因应用于的文件而异,则以下列表中符号常量之一的定义可以被省略在 <limits.h> 头文件中。像 Linux 这样对不同文件系统类型具有可变最大路径长度的系统不应定义 PATH_MAX - Andrew Henle
显示剩余2条评论

8
尝试在stdlib.h中使用realpath()
char filename[] = "../../../../data/000000.jpg";
char* path = realpath(filename, NULL);
if(path == NULL){
    printf("cannot find file with name[%s]\n", filename);
} else{
    printf("path[%s]\n", path);
    free(path);
}

2

还有一个小型的路径库cwalk,可跨平台使用。它有cwk_path_get_absolute来实现此功能:

#include <cwalk.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  char buffer[FILENAME_MAX];

  cwk_path_get_absolute("/hello/there", "./world", buffer, sizeof(buffer));
  printf("The absolute path is: %s", buffer);

  return EXIT_SUCCESS;
}

输出:

The absolute path is: /hello/there/world

0
如果realpath()不可用(在Windows系统中),请使用_fullpath()

如果你使用的是Windows操作系统,你可以使用GetFullPathName函数(正如2008年的问题所提到的)。此外,在2023年,你可能想要使用标准库的filesystem::absolute函数。 - undefined

0

也可以尝试使用 "getcwd"

#include <unistd.h>

char cwd[100000];
getcwd(cwd, sizeof(cwd));
std::cout << "Absolute path: "<< cwd << "/" << __FILE__ << std::endl;

结果:

Absolute path: /media/setivolkylany/WorkDisk/Programming/Sources/MichailFlenov/main.cpp

测试环境:

setivolkylany@localhost$/ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.6 (jessie)
Release:    8.6
Codename:   jessie
setivolkylany@localhost$/ uname -a
Linux localhost 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
setivolkylany@localhost$/ g++ --version
g++ (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

5
100K 用于一个路径?!肯定 5K 就够了吧?或者 PATH_MAX? - Jachdich
由于getcwd解析当前工作目录,因此该代码对名为“/some/file/compiled/with/absolute.name”的__FILE__可能会失败。 - Simon Sobisch

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