为什么’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