C++ macosxc++。应用程序找不到fopen()文件

C++ macosxc++。应用程序找不到fopen()文件,c++,macos,fopen,C++,Macos,Fopen,我的mac.app所在的目录中有一个文件夹,其中有一个名为test.ssm的文件。此函数试图打开此文件: FILE *input_file = fopen("./data/maps/test.ssm", "r"); 问题是,应用程序不断获取代码:EXC_BAD_ACCESS,因为它无法打开此文件。我的项目是使用一个普通的COCOA项目在xcode中建立的。这是一个opengl/glut应用程序。问题在于.app是一个包,因此它实际上也是一个目录结构,而不是一个“普通”文件。您的实际可执行文件位

我的mac.app所在的目录中有一个文件夹,其中有一个名为test.ssm的文件。此函数试图打开此文件:

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

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

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

通过右键单击
应用程序并选择
查看软件包内容
,您实际上可以浏览该应用程序的目录结构

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

如果您希望您的
/data
目录位于
.app
包中,那么您只需在路径中添加足够的
./
,即可从
/MacOSX
目录进入
.app
的根目录,在那里可以找到
/data
目录


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

如上所述,
.app
是一个包,或Mac OS X GUI视为文件的特殊文件夹。
.app
不是正在运行的,正在运行的是
您的.app/Contents/MacOS/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 );
}

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

是的,我理解这一点,但我不知道将文件夹放在哪里。不管我把它放在哪里,它似乎都不想工作。你知道我把它放在.app目录的什么地方吗?你必须把文件放在可执行文件所在的同一目录中,或者至少相对于它。如我在回答中所述,您可以通过右键单击
.app
并选择
查看软件包内容来浏览软件包内容以查看可执行文件的位置。我已将文件夹放在同一目录中,但它仍然不工作???我不知道发生了什么。文件
test.ssm
确实存在,并且您对该文件拥有正确的权限,对吗?该文件存在并且具有正确的权限。如果我将文件夹放在硬盘的根目录下,并删除fopen调用中的点,则应用程序可以工作,但我不想这样做。在使用应该创建的文件指针之前,您应该始终测试
fopen()
中的返回值。这样,就避免了由于访问空指针而导致的崩溃。此外,在C++中,您应该使用<代码> <代码>,而不是<代码> <代码>或<代码> <代码>。