【问题标题】:fopen works in main but not in a function in another filefopen 在 main 中有效,但在另一个文件中的函数中无效
【发布时间】:2020-11-20 12:32:05
【问题描述】:

我正在尝试使用 fopen 打开一个 .bdf 字体文件。这在 main() 中调用时工作正常,但是当我尝试在另一个文件中的函数中加载字体时,我收到一条 Permission Denied 消息,错误号为 13 来自 errno。

我正在使用 makefile 编译它并在树莓派上运行它:

./sudo clock

这是两个文件

main.cc

#include <stdio.h>
#include <errno.h>

#include "clock.h"

int main(int argc, char *argv[]) {
  const char *path = "/home/pi/rpi-rgb-led-matrix/clock/fonts/6x12.bdf";
  FILE *f = fopen(path, "r");
  if (f == NULL) {
    perror(path);
    fprintf(stderr, "Failed load %d <-- Main\n", errno);
  } else {
    fprintf(stderr, "Font load succeeded <-- Main\n");
  }
  
  // Set up Clock Face
  initialiseClockFace();

  return 0;
}

时钟.h

#include <stdio.h>
#include <errno.h>

void initialiseClockFace();

时钟.cc

#include "clock.h"

void initialiseClockFace() {
  const char *path = "/home/pi/rpi-rgb-led-matrix/clock/fonts/6x12.bdf";
  FILE *f = fopen(path, "r");
  if (f == NULL) {
    perror(path);
    fprintf(stderr, "Failed load %d <-- Clock\n", errno);
  } else {
    fprintf(stderr, "Font load succeeded <-- Clock\n");
  }

}

运行时,它会打印以下内容:

Font load succeeded <-- Main
/home/pi/rpi-rgb-led-matrix/clock/fonts/6x12.bdf: Permission denied
Failed load 13 <-- Clock

看着https://pubs.opengroup.org/onlinepubs/009695399/functions/fopen.html, 除非我弄错了,错误号 13 是:

 [EROFS]
 The named file resides on a read-only file system and mode requires write access.

我尝试在 stackoverflow 和 Google 上搜索我的问题,但似乎找不到任何答案。非常感谢任何帮助。

【问题讨论】:

  • 似乎第一个fopen 已锁定文件,因此第二个fopen 失败。由于您没有使用任何一个文件句柄,因此很难确定建议什么作为替代方案。在调用initializeClockFace 之前,您可以尝试使用fclose 关闭main 中的文件,或者您可以将文件句柄从main 传递给initializeClockFace,而不是再次尝试打开它。
  • 你错了,错误 13 并不意味着该页面上列出的第 13 个错误。 errno 不是这样工作的。您需要检查您的头文件以确定该页面上列出的错误名称中的哪些在您的上定义系统错误 13.
  • 假设您的 Raspberry 运行 Linux 变体,错误编号 13 很可能是 EACCESperror 消息“Permission denied”也暗示了这一点。

标签: c fopen permission-denied errno


【解决方案1】:

可能由于 main 中的 fopen 调用,文件被锁定。 一般来说,我建议避免使用 C 函数。你应该使用 std::fstream 因为它会自动释放你的句柄。

在 initialiseClockFace 之前检查它是否适用于 fclose 调用。

【讨论】:

  • 好建议,但在这种情况下,文件在调用 initializeClockFace 函数之前不会被释放。
  • 我最初只在initialClockFace 函数中有fopen 调用,但将它复制到主函数以查看它是否可以在那里工作。当 fopen 调用不在主函数中时,我收到了相同的失败消息。我会尝试使用 fstream 看看是否有效。
  • @user794895 我认为您无法正确复制您的代码。查看您的错误消息the mode requires write access,但在上面的代码中,您显然要求读取访问权限"r",所以这没有意义。将 fopen 调用从一个函数移动到另一个函数不应停止它的工作(如果这是唯一的变化)。
  • 无论使用 fopen 还是 fstream,这与所讨论的错误完全无关,假设其他一切都相同。
  • fstream 也无法加载,所以没有解决问题。 @john 我复制/粘贴了代码,所以这绝对是我的程序中的内容。
【解决方案2】:

我已经解决了这个问题,我在一个没有正确关闭它的类中调用另一个函数。

感谢您抽出宝贵时间提供帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多