我发布此内容是为了记录我的问题,请参阅下面我的自我回答。
无论我尝试什么,
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);
}
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) 中,意思是
没有这样的文件或目录 (POSIX.1-2001)。ENOENT
通常,当指定路径时会出现此错误 - 名称不存在,或者名称中的组件之一不存在 路径名的目录前缀不存在,或者 指定的路径名是一个悬空符号链接。
我觉得这个解释很清楚。在您的情况下,您当前的
工作目录中可能没有任何
path/
目录,或者您确实有 path/to/my/
目录,但没有任何 file
条目等(例如 path/
存在,但没有 to/
里面)....
您可以通过不仅显示
errno
(使用 strerror(errno)
或 perror
)而且还显示工作目录来改进您的程序。请参阅getcwd(3)。或者您可以让您的用户猜测。您的用户可能更改了工作目录,例如使用他的 unix shell的
cd
内置命令。
使用 _tfopen(文件名,“r”)