C语言 为什么“fopen”返回空指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5987626/
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 08:38:19  来源:igfitidea点击:

Why does 'fopen' return a NULL pointer?

cnullfopenfwrite

提问by k787

I'm working on a simple file splitter/merger program in the C programming language. The problem is, for some reason fopenreturns NULL, and because of that, my program is crashing at the fwritestatement. How do I fix this?

我正在使用 C 编程语言开发一个简单的文件拆分器/合并程序。问题是,出于某种原因,fopen返回 NULL,因此,我的程序在fwrite语句处崩溃。我该如何解决?

Here is the C file:

这是C文件:

int SplitFile(char* filename, char* output, size_t size)
{
    char current_file_name[256];
    int file_count = 0, i = 0;
    FILE *file = fopen( filename, "rb" );
    printf("split %s into chunks of %d named\n", filename, size);

    if (!file)
       return E_BAD_SOURCE;
    else
    {
        output = (char *) malloc(size * sizeof(char));
        if (output == NULL)
            return E_NO_MEMORY;
        else
        {
            int bytes_read = 0;
            FILE *outFile;
            do
            {
                bytes_read = fread(output, sizeof(char), size, file );
                sprintf(current_file_name, "%s%04lu\n", "part", file_count++);
                outFile = fopen (current_file_name, "wb" );  // THIS RETURNS NULL
                fwrite(output, sizeof(char), bytes_read, outFile); //CRASHES ON THIS LINE
            }
            while ( bytes_read > 0 )
                ;

            //fclose(outFile);
        }
    }
    fclose(file);
    printf("...\n");
    return 0;
}

回答by Gabe

The proper thing to do is check errnowhen fopenreturns NULL.

正确的做法是检查errno何时fopen返回NULL

I'm going to guess that your problem is that you're trying to write to a filesystem that doesn't allow \nin filenames, but it could be a permissions issue as well.

我猜你的问题是你试图写入一个不允许\n文件名的文件系统,但这也可能是一个权限问题。

回答by JaredPar

There are many reasons fopencan return NULLincluding (but certainly not limited to):

有很多原因fopen可以退货,NULL包括(但肯定不限于):

  • The file doesn't exist
  • The file is opened in a mode that doesn't allow other accesses
  • The network is down
  • The file exists, but you don't have permissions
  • A file exists with the name you gave, but the current directory of the process is not what you expected so the relative pathname fails to find and open the file.
  • 该文件不存在
  • 文件以不允许其他访问的模式打开
  • 网络挂了
  • 该文件存在,但您没有权限
  • 存在具有您指定名称的文件,但该进程的当前目录不是您所期望的,因此相对路径名无法找到并打开该文件。

The way to find out which is responsible is to dig into the errnocode.

找出谁负责的方法是深入研究errno代码。

However just because you resolve this particular error doesn't mean you can assume fopenwill never return NULL. When dealing with I/O operations your code simply has to expect failure. It's not possible to predict the success of I/O operations, and they can always fail.

然而,仅仅因为您解决了这个特定错误并不意味着您可以假设fopen永远不会返回NULL。在处理 I/O 操作时,您的代码只需要预料到会失败。无法预测 I/O 操作的成功,它们总是会失败。

回答by Sohail xIN3N

It means that the file might not exist or some permission error occurred while accessing a file such as "Read-Only" or "Write-Protected", so in those cases fopen will return 0 (a NULL pointer). On success it will return a file pointer as a handler.

这意味着该文件可能不存在或在访问文件时发生了某些权限错误,例如“只读”或“写保护”,因此在这些情况下 fopen 将返回 0(空指针)。成功时,它将返回一个文件指针作为处理程序。

fp=fopen("c:\\ABC.txt", "r");cannot be the same as fp=fopen("c:\\abc.txt", "r");.

fp=fopen("c:\\ABC.txt", "r");不能与fp=fopen("c:\\abc.txt", "r");.

Use //instead of \\in a Linux environment.

在 Linux 环境中使用//而不是\\

P.S.:In Linux and Unix-like operating systems file names are case-sensitive.

PS:在 Linux 和类 Unix 操作系统中,文件名区分大小写

回答by Vinoj John Hosan

In Unix, for fopen(), there is no reason to prepend ./ to a filename passed to fopen().

在 Unix 中,对于 fopen(),没有理由在传递给 fopen() 的文件名前加上 ./。

回答by Riki137

In my case, i was reading the same file all over again in a while loop and forgot to close it.

就我而言,我在 while 循环中再次读取同一个文件,但忘记关闭它。

I used a function for reading the file and finding a match and the function had a return;statement that terminated the function before doing fclose(fp):D

我使用了一个函数来读取文件并找到匹配项,并且该函数有一个return;语句在执行之前终止了该函数fclose(fp):D

回答by Sanya Tayal

The path given for the file is checked from wherever the executable is present. In my case I was opening the text file in c file when both were present at the same place. It was continuously giving the error of file not found. Placed the file in the folder of executable and it started working.

从可执行文件所在的位置检查为文件提供的路径。在我的情况下,当两者都在同一个地方时,我正在打开 c 文件中的文本文件。它不断给出找不到文件的错误。将文件放在可执行文件的文件夹中,它开始工作。

回答by tuket

In my case, it was because I was trying to create the file in a directory that does NOT exist.

就我而言,这是因为我试图在不存在目录中创建文件。

回答by Amir

Is fopen for write return NULL in the first run?

fopen for write 在第一次运行时是否返回 NULL?

I noticed that in the while you keep open files for write but not closing them.

我注意到在您保持打开文件进行写入但不关闭它们的同时。

Try to add fclose(outFile) after fwrite:

尝试在 fwrite 后添加 fclose(outFile):

outFile =  fopen ( current_file_name , "wb" );    
fwrite(output, sizeof( char ), bytes_read, outFile); 
fclose(outFile)

It is possible you open more files than your OS allows.

您打开的文件可能比操作系统允许的多。

回答by Tometzky

As Gabe said your problem is newline in filename which is illegal in Windows.

正如 Gabe 所说,您的问题是文件名中的换行符,这在 Windows 中是非法的。

But why don't you just use split from GNU Core Utilities. Installed by default on Unices/Linux, can be downloaded for Windows from GnuWin32 project.

但是为什么不直接使用 GNU Core Utilities 的 split 呢?默认安装在 Unices/Linux 上,可以从GnuWin32 项目下载 Windows 。

split --suffix-length=4 --numeric-suffixes --bytes=1M - part < filename