The AppKit/Cocoa classes require an NSApplication object to be initialized in order to handle user input (among other things). Adding this line to the top of your main function should do the trick:
int main(int argc, char *argv[])
{
[NSApplication sharedApplication]; // ** Add this **
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSSavePanel *sPanel = [NSSavePanel savePanel];
int result = [sPanel runModal];
if (result == NSOKButton) {
NSString * filename = [sPanel filename];
const char * fileStr = [filename UTF8String];
printf("%s\n", fileStr);
}
[pool drain];
return 0;
}
More information about this can be found in the documentation for NSApplication, particularly these points:
Every application must have exactly one instance of NSApplication (or
a subclass of NSApplication). Your program’s main() function should
create this instance by invoking the sharedApplication class method.
NSApplication performs the important task of receiving events from the
window server and distributing them to the proper NSResponder objects.
NSApp translates an event into an NSEvent object, then forwards the
NSEvent object to the affected NSWindow object.
Along the lines of bbum and danielpunkass's comments below, this isn't the way you'd really write a Cocoa application, and while it does make your immediate issue go away, it's not a complete or completely correct solution. To expand on Daniel's comment, and to get you started easily, create a new Cocoa application project. Open up the application delegate class (created for you), and put your code in the -applicationDidFinishLaunching:
method. As implied by its name, that method is called after the application has finished launching, and everything is setup such that you can use the AppKit classes normally. As you gain more experience, you'll better understand the typical Cocoa application architecture and can move on to creating user interfaces, etc.