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

时间:2018-02-12 06:27:57

标签: c segmentation-fault fopen

我已发布此文件以记录我的问题,请参阅下面的自我解答。

无论我尝试什么,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);
}

1 个答案:

答案 0 :(得分:1)

记录

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) - ...)失败的原因。受过良好教育的用户可以管理(可能在他的系统管理员的帮助下)。

ENOENTerrno(3)中记录为

  

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

     

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

我发现这个解释很清楚。在您的情况下,您当前的working directory可能没有任何path/目录,或者您没有任何path/to/my/条目的file目录等(例如{{ 1}}存在但内部没有path/)....

您不仅可以显示to/(使用errnostrerror(errno)),还可以显示工作目录,从而改进您的计划。见getcwd(3)。或者您可以让用户猜测它。您的用户可能已更改了工作目录,例如使用unix shellperror内置命令。