c - 使用 fopen 和测试 NULL 的奇怪 C 行为

标签 c if-statement fopen

我有以下代码来打开输入和输出文件:

if ((source_file_ptr = fopen(source_filename, "rb")) == NULL) {
  error("unable to open input file");
}
if ((output_file_ptr = fopen(output_filename, "wb")) == NULL) {
  error("unable to open output file");
}

这是在打开文件时捕获错误的好简单方法。

然而,在对我的程序进行一些整体编辑后,程序现在崩溃了,而不是捕获无效的输出文件。

我尝试了几件事都没有成功,但有趣的是,当我尝试这个时:

if ((output_file_ptr = fopen(output_filename, "wb")) == NULL) printf("fail");
exit(0);
if ((source_file_ptr = fopen(source_filename, "rb")) == NULL) {
  error("unable to open input file");
}
if ((output_file_ptr = fopen(output_filename, "wb")) == NULL) {
  error("unable to open output file");
}

它将打印“fail”(并且显然在没有更多洞察力的情况下退出)。

但是如果我注释掉 exit(0) 行,它将再次表现出相同的崩溃行为,而不会打印“失败”,也不会捕获错误。

我无法解释为什么这是...我怀疑是悬空指针,但函数中唯一的前面几行代码已经用大括号括在 if-else if-else 中。上面只声明了几个其他函数,但我已经检查并确保它们都包含在大括号中。

我还在学习 C,对这里发生的事情有什么想法吗?
非常感谢!

注意:用大括号括起 printf("fail") 不会改变我观察到的行为。

编辑:上面的附加代码:

if (fread(&file_struct, sizeof(file_struct), 1, source_file_ptr) < 1) {
   error("unable to read %s", source_filename);
}
else {
   error_check(file_struct);

  if (fwrite(&file_struct, sizeof(file_struct), 1, output_file_ptr) < 1) {
     error("unable to write file header");
  }
}

最佳答案

我要检查的第一件事是 source_filename 是一个有效的 C 字符串。然后我会以同样的方式检查 output_filename

如果事实证明您的更改以某种方式破坏了它们中的一个或两个,那么您将进入未定义的领域行为。

在这里使用调试器是理想的选择,因为您可以在该代码的开头设置一个断点,然后单步执行,检查您将要使用的变量。

您应该检查的另一件事是您对 error 的调用是否实际返回(而不是调用 exit)。

如果他们这样做了,即使 fopen 调用返回 NULL,您仍会将其传递给 fread 和/或 fwrite,绝对不能。

由于您的第二个案例打印了 "fail",因此可以肯定您在打开输出文件时遇到了一些问题。使用 NULL 句柄并不是一件好事。

如果该函数确实返回,那么您应该使用类似的东西:

if ((source_file_ptr = fopen(source_filename, "rb")) == NULL) {
  error("unable to open input file");
  return;
}
if ((output_file_ptr = fopen(output_filename, "wb")) == NULL) {
  fclose (source_file_ptr);
  error("unable to open output file");
  return;
}

关于c - 使用 fopen 和测试 NULL 的奇怪 C 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9924148/

相关文章:

c - 如何在 C 中使用 printf 遍历 unicode 字符并将它们打印在屏幕上?

ios - 检查 Core Data managedObject 中的多个 nil 值?

c++ - 将 array.size() 与负值进行比较时出现 if 条件的意外行为

php - 我是使用 fopen 还是 curl 加载给定 PHP 中的 URL 的 XML 文件

android ndk native 代码 fopen() 路径

c - 打开二进制文件

c - 超出范围是否释放了(字符)数组的内存?

c - 在 C 中释放分配的内存时堆损坏

c - epoll_wait返回怎么样?它是否对所请求的 I/O 的文件描述进行排序?

java - 为什么我的 IF ELSE 语句默认向后?