C++ macosxc++。应用程序找不到fopen()文件
我的mac.app所在的目录中有一个文件夹,其中有一个名为test.ssm的文件。此函数试图打开此文件: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是一个包,因此它实际上也是一个目录结构,而不是一个“普通”文件。您的实际可执行文件位
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++中,您应该使用<代码> <代码>,而不是<代码> <代码>或<代码> <代码>。