为什么 fopen 打不开现有文件? (返回 NULL,错误号 ENOENT)

问题描述 投票:0回答:2

我发布此内容是为了记录我的问题,请参阅下面我的自我回答。

无论我尝试什么,

fopen(...)
都无法在存在并返回NULL的路径上打开
现有
文件。 我正在从
~/path
中的 bash 脚本执行程序。程序文件存储在
~/path/to

int main(void) {
  const char* filename = "my/file"
  FILE* fp = NULL;
  fp = fopen(filename, "r"); // file is still NULL, segfaults on indirection
  if (!fp) exit(1);
  fclose(fp);
}
c segmentation-fault fopen
2个回答
4
投票

fopen(3) 被记录为可能失败:

否则,返回 NULL 并设置

errno
来指示错误。

所以你至少应该编码:

FILE* fp = fopen(filename, "r");
if (fp == NULL) { perror(filename); exit(EXIT_FAILURE); };

fopen
甚至不会尝试创建您打开仅供阅读的文件。

根据经验,总是需要检查

fopen
(如上所述的最小值)是否失败,并向您的用户报告(在errno(3)perror(3)的帮助下), strerror(3) - 用作
strerror(errno)
- ...) 失败的原因。受过教育的用户将能够进行管理(也许在系统管理员的帮助下)。

ENOENT
记录在 errno(3) 中,意思是

ENOENT
没有这样的文件或目录 (POSIX.1-2001)。

通常,当指定路径时会出现此错误 - 名称不存在,或者名称中的组件之一不存在 路径名的目录前缀不存在,或者 指定的路径名是一个悬空符号链接。

我觉得这个解释很清楚。在您的情况下,您当前的

工作目录
中可能没有任何 path/ 目录,或者您确实有
path/to/my/
目录,但没有任何
file
条目等(例如
path/
存在,但没有
to/
里面)....

您可以通过不仅显示

errno
(使用
strerror(errno)
perror
)而且还显示工作目录来改进您的程序。请参阅getcwd(3)。或者您可以让您的用户猜测。您的用户可能更改了工作目录,例如使用他的
unix shell
cd 内置命令。


0
投票

使用 _tfopen(文件名,“r”)

© www.soinside.com 2019 - 2024. All rights reserved.