为什么’fopen’返回NULL指针?

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

这是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; } 

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

我猜你的问题是你正在尝试写入文件系统,该文件系统不允许在文件名中使用\n ,但它也可能是权限问题。

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

  • 该文件不存在
  • 该文件以不允许其他访问的模式打开
  • 网络瘫痪了
  • 该文件存在,但您没有权限
  • 存在一个文件,其中包含您提供的名称,但该进程的当前目录不是您所期望的,因此相对路径名无法找到并打开该文件。

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

但是,仅仅因为您解决此特定错误并不意味着您可以假设fopen将永远不会返回NULL 。 在处理I / O操作时,您的代码只需要预期失败。 不可能预测I / O操作的成功,它们总是会失败。

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

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

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

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

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

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

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

在第一次运行时,fopen for write返回NULL吗?

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

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

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

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

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

在我的情况下,我在一个while循环中再次读取相同的文件,忘了关闭它。

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