【问题标题】:Mac osx c++ .app cannot find a file fopen()Mac osx c++ .app 找不到文件 fopen()
【发布时间】:2026-02-02 14:35:02
【问题描述】:

我在与我的 mac .app 相同的目录中有一个文件夹,其中有一个名为 test.ssm 的文件。这是试图被这个函数打开:

FILE *input_file = fopen("./data/maps/test.ssm", "r");

问题是应用程序不断获取代码:EXC_BAD_ACCESS,因为它无法打开此文件。我的项目是使用普通的 coccoa 项目在 xcode 中设置的。这是一个 opengl/glut 应用程序。

【问题讨论】:

  • 在使用应该创建的文件指针之前,您应该始终测试来自fopen() 的返回值。这样,您可以避免由于访问空指针而导致的崩溃。此外,在 C++ 中,您可能应该使用 <iostream> 而不是 <stdio.h><cstdio>

标签: c++ macos fopen


【解决方案1】:

问题在于.app 是一个包,因此它实际上也是一个目录结构,而不是“普通”文件。您的实际可执行文件位于目录YourApp.app/Contents/MacOSX/ 中。因此,当您使用以./ 开头的相对路径在C 代码中打开文件时,可执行文件实际上是在YourApp.app/Contents/MacOSX/ 目录中查找您的文件,而不是在安装.app 包的父目录中.

您实际上可以通过右键单击.app 并选择View Package Contents 来浏览其目录结构。

如果您要将文件放置在您希望从可执行文件中访问的文件系统中,请将它们打包在.app 中,或者将它们放在.app 之外,并在您的文件中放置足够的../文件访问,让您脱离.app 目录结构,进入安装.app 的父目录。

如果您希望您的 /data 目录位于 .app 包中,那么您只需在路径中添加足够的 ../ 即可让您离开 /MacOSX 目录并进入.app 将在其中找到 /data 目录。

最后,如果您需要知道可执行文件所在的绝对路径,您始终可以使用 mach-o/dyld.h 内部的 C 函数 _NSGetExecutablePath(即,您不需要 Objective-C)。从那里您可以修改路径以获取相对于可执行文件所在位置的文件系统中的任何其他目录,方法是将其修剪到正确的父目录,然后将路径名附加到要打开的文件中。

【讨论】:

  • 是的,我理解这一点,但我不知道将文件夹放在哪里。无论我把它放在哪里,它似乎都不想工作。你知道我把它放在 .app 目录的什么地方吗?
  • 您必须将文件放在可执行文件所在的目录中,或者至少相对于它。如我的回答所述,您可以通过右键单击.app 并选择View Package Contents 来浏览包内容以查看可执行文件的位置。
  • 我把文件夹放在同一个目录下还是不行???我不知道发生了什么。
  • 文件test.ssm确实存在,并且您对该文件具有正确的权限,对吧?
  • 文件存在且权限正确。如果我的硬盘驱动器根目录中有文件夹并删除我的 fopen 调用中的点,则应用程序可以工作,但我不想这样做。
【解决方案2】:

如上所述,.app 是一个包,或者是 Mac OS X GUI 将其视为文件的特殊文件夹。 .app 不是正在运行的,正在运行的是your.app/Contents/MacOS/your,当前目录指的是your.app/Contents/MacOS/。如果您不介意在您的应用程序中使用 Objective-C(如果您还没有链接 Foundation.framework,我建议您找到另一种方法),您可以这样做来获取应用程序包的路径:

const std::string GetApplicationDirectory()
{
    id info = [[NSBundle mainBundle] infoDictionary];
    NSString *bundleID = [info objectForKey: @"CFBundleIdentifier"];

    NSWorkspace *wp = [[NSWorkspace alloc] init];
    NSString *app   = [wp absolutePathForAppBundleWithIdentifier: bundleID];

    const char *str = [[app substringToIndex: [app length] - [[app lastPathComponent] length]]] cStringUsingEncoding: NSASCIIStringEncoding];
    return std::string( str );
}

【讨论】:

    【解决方案3】:

    您必须在 Mac OS X 中提供绝对文件路径,因为 Mac OS X 是为使用文件对话框或类似的东西而构建的。

    【讨论】: