C语言 C fopen 写入失败,errno 为 2

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15753090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:54:46  来源:igfitidea点击:

C fopen fails for write with errno is 2

cfopenerrno

提问by JPM

I do not understand why this is seemingly failing with errno of 2:

我不明白为什么这似乎以 2 的 errno 失败:

char debugText [256];
sprintf (debugText, "C:\List.txt");
dfile = fopen( debugText, "w");
fprintf ( dfile, "  err %d \n", errno);

I say seemingly because while dfile is NULL the file gets created and is filled with my output.

我说似乎是因为当 dfile 为 NULL 时,文件被创建并填充了我的输出。

so what is going on ?

那么发生了什么 ?

回答by Keith Thompson

All this tells you is that errnohad the value 2 after your fopencall. You don't know that the call failed, because you didn't check whether dfile == NULL. If the output was actually written to the file, presumably the fopencall succeeded and the errnovalue was left over from some previous call, likely one you didn't make explicitly.

所有这一切都告诉您,errno在您fopen调用后值为 2 。你不知道调用失败,因为你没有检查dfile == NULL. 如果输出实际上已写入文件,则可能fopen调用成功并且该errno值是从先前的某个调用(可能是您没有明确进行的调用)遗留下来的。

Failing calls can set errnoto some non-zero value, but successful calls don'tset errnoto 0. To check for errors, you need to

失败的调用可以设置errno为一些非零值,但成功的调用不会设置errno为 0。要检查错误,您需要

  • Set errnoto 0 before the call;
  • Make the call and check the value it returned to see whether it succeeded or failed; and
  • Check the value of errnoafter the call -- but onlyif you know it failed (otherwise the value of errnois meaningless).
  • errno调用前置0;
  • 进行调用并检查返回的值,看是成功还是失败;和
  • 检查errno调用后的值——但前提是你知道它失败了(否则值errno是没有意义的)。

If defile == NULL, then the fprintfcall has undefined behavior; it will probably fail.

如果defile == NULL,则fprintf调用具有未定义的行为;它可能会失败。

On the other hand, you say that dfileis NULL. How do you know that? Your code doesn't check it. (If the fopencall really did fail, could the contents of C:\List.txtbe left over from a previous run of your program?)

另一方面,你说那dfileNULL。你怎么知道?您的代码不会检查它。(如果fopen调用确实失败了,是否可以C:\List.txt从之前的程序运行中遗留下来的内容?)

What output do you get from this program?

你从这个程序得到什么输出?

#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;
}

回答by Johnny Mnemonic

2 ENOENT No such file or directory.  A component of a specified pathname
         did not exist, or the pathname was an empty string.

Here is a list of the error codes:

以下是错误代码列表:

http://www.thegeekstuff.com/2010/10/linux-error-codes/

http://www.thegeekstuff.com/2010/10/linux-error-codes/

But you should check if fopen()returned NULLfirst because this value in errnomight be left over from something else.

但是你应该检查是否首先fopen()返回,NULL因为这个值errno可能是其他东西遗留下来的。

回答by Jonathan Leffler

No library function ever sets errnoto zero.

没有库函数设置errno为零。

You should only check errnoafter a function reports an error.

您应该只errno在函数报告错误后进行检查。

For example, your code should be:

例如,您的代码应该是:

if ((dfile = fopen(debugText, "w")) == 0)
    ...then fopen() failed and errno is relevant...

If the function does not report failure, the value in errnomay be anything. For example, on Solaris, you often end up with errnoset to ENOTTYafter a successful operation, because stdoutis not connected to a terminal. It doesn't mean anything actually went wrong; it just means that a test for whether standard output is a terminal failed (because it isn't a terminal).

如果函数没有报告失败,则输入的值errno可以是任何值。例如,在 Solaris 上,您经常会在操作成功后以errnoset toENOTTY结束,因为stdout没有连接到终端。这并不意味着实际上出了什么问题;它只是意味着测试标准输出是否是终端失败(因为它不是终端)。