C fopen 写入失败,errno 为 2
Posted
技术标签:
【中文标题】C fopen 写入失败,errno 为 2【英文标题】:C fopen fails for write with errno is 2 【发布时间】:2013-03-23 02:19:27 【问题描述】:我不明白为什么这似乎以 errno 为 2 失败:
char debugText [256];
sprintf (debugText, "C:\\List.txt");
dfile = fopen( debugText, "w");
fprintf ( dfile, " err %d \n", errno);
我说的似乎是因为当 dfile 为 NULL 时,文件被创建并填充了我的输出。
那是怎么回事?
【问题讨论】:
dfile
是什么类型? NULL
的测试在哪里?
看看strerror()
,它会返回一个字符串,为您解释errno
。
(对于 googlers)对我来说,文件没有写权限。在 Windows 上:右键单击 > 属性 > 安全 > 编辑。然后允许所有用户修改
@SergioBasurco 也许这是一个更好的解决方法,使文件指向允许普通用户写入的位置。不是每个人都在他们的电脑上拥有管理员访问权限,这些权限不应用于纠正编程错误。
【参考方案1】:
这一切都告诉你,errno
在你调用fopen
之后的值为 2。你不知道调用失败,因为你没有检查是否dfile == NULL
。如果输出实际上已写入文件,则可能是 fopen
调用成功,而 errno
值是先前调用留下的,可能是您没有明确调用的。
失败的调用可以将errno
设置为某个非零值,但成功的调用不要将errno
设置为0。要检查错误,您需要
errno
设置为0;
进行调用并检查它返回的值,看它是成功还是失败;和
在调用后检查errno
的值——但仅如果你知道它失败了(否则errno
的值没有意义)。
如果defile == NULL
,则fprintf
调用具有未定义的行为;它可能会失败。
另一方面,你说dfile
是NULL
。你怎么知道?你的代码没有检查它。 (如果fopen
调用真的失败了,C:\List.txt
的内容是否会从您的程序的先前运行中遗留下来?)
你从这个程序得到什么输出?
#include <stdio.h>
#include <errno.h>
int main(void)
char debugText [256];
FILE *dfile;
sprintf (debugText, "C:\\List.txt");
dfile = fopen( debugText, "w");
if (dfile == NULL)
printf("fopen failed, errno = %d\n", errno);
else
printf("fopen succeeded\n");
return 0;
【讨论】:
我看到 dfile 为 NULL,因为我在调试模式下单步执行。那是我开始抓取 errno 的时候。 您需要检查defile == NULL
是否在您的程序中,如果是则不要尝试写入文件。要验证fopen()
失败的原因,请按照我对errno
的建议进行操作。假设您在 Windows 系统上,打开 "C:\\List.txt"
进行输出不应以 errno==2
失败,这意味着“没有这样的文件或目录”。 (您是在 Windows 上,对吗?而不是在 Cygwin 下?)
@JPM:试试我刚刚添加到答案中的程序。【参考方案2】:
2 ENOENT No such file or directory. A component of a specified pathname
did not exist, or the pathname was an empty string.
这里是错误代码列表:
http://www.thegeekstuff.com/2010/10/linux-error-codes/
但是您应该首先检查fopen()
是否返回NULL
,因为errno
中的这个值可能是其他东西留下的。
【讨论】:
【参考方案3】:没有库函数将errno
设置为零。
您应该只在函数报告错误后检查errno
。
例如,您的代码应该是:
if ((dfile = fopen(debugText, "w")) == 0)
...then fopen() failed and errno is relevant...
如果函数不报告失败,errno
中的值可能是任何值。例如,在 Solaris 上,您经常在成功操作后将errno
设置为ENOTTY
,因为stdout
没有连接到终端。这并不意味着实际上出了什么问题。它只是意味着测试标准输出是否是终端失败(因为它不是终端)。
【讨论】:
如果文件确实存在 fopen 应该删除然后创建一个新文件。显然路径不是空的,路径也不是不存在的:C:\ 所以我不明白为什么 dfile 为 NULL。除非那是 VS2010 的异常? 你没有证明dfile == NULL
;事实上,由于下面的fprintf()
使用它,所以dfile
不可能为空(如果它为空,您可能会在fprintf()
中崩溃)。您必须修改代码以明确测试 dfile
,然后我才愿意相信您的断言 dfile
为空(并在 dfile
以外的频道上报告错误)。【参考方案4】:
在我的情况下,我在尝试打开文件以写入具有 FAT 文件系统的挂载闪存驱动器时收到了errno == 2
;事实证明,如果文件不符合8.3 rule,fopen
返回NULL
并将errno
设置为ENOENT
。
有必要说,我在嵌入式系统上遇到过这种情况,在 Windows 上应该不是问题。
【讨论】:
是的,我的错。编辑了我的答案。以上是关于C fopen 写入失败,errno 为 2的主要内容,如果未能解决你的问题,请参考以下文章