Techniques for printing an NSString to STDOUT

Recently, I found myself in need of a quick way to dump an NSString to stdout.

The Foundation APIs provide NSLog(), but NSLog is no good for anything but debugging. First of all, the output is prepended with a timestamp and other garbage, and secondly, it goes to stderr.

Here are some possible techniques for printing NSStrings to stdout.

On-the-fly C string conversion

One method of dumping an NSString to stdout is to convert the object to a C string and then use good old fprintf.

#import Foundation/Foundation.h

int main (int argc, char *argv[])
{
     NSString *str = @"Hello, World";

     fprintf(stdout, "%s", [str UTF8String]);

     return 0;
}

Print NSData to STDOUT filehandle

Another way of dumping a string to STDOUT is to convert the NSString to an NSData object and use the NSFileHandle method writeData:.

#import Foundation/Foundation.h

int main (int argc, char *argv[])
{
     NSFileHandle *stdout = [NSFileHandle fileHandleWithStandardOutput];
     NSString *str = [NSString stringWithString: @"Hello, World"];
     NSData *strData = [str dataUsingEncoding: NSASCIIStringEncoding];

     [stdout writeData: strData];
     return 0;
}

This is certainly not elegant.

A superior way: writeToFile

That's right. Remember how everything in UNIX is a file? In my humble opinion, the most beautiful and elegant way to dump an NSString to stdout is unquestionably the following:

#import Foundation/Foundation.h

int main (int argc, char *argv[])
{
     NSString *str = @"Hello, World";

     // And here comes the magic one-liner
     [str writeToFile:@"/dev/stdout" atomically: NO];

     return 0;
}

Yes, we just write the string to the STDOUT character device using a Foundation string method. It's short, it's simple and it does exactly what we want it to, without any crusty overhead. And if we want even greater convenience, we can just wrap it in a function:

void NSPrint (NSString *str)
{
     [str writeToFile: @"/dev/stdout" atomically: NO];
}

This will allow us to dump out formatted NSStrings reasonably elegantly.

NSPrint([NSString stringWithFormat: @"%@ %@", str1, str2]);

But this is even better:

static void NSPrint(NSString *format, ...)
 {
    va_list args;
    
    va_start(args, format);
    NSString *string  = [[NSString alloc] initWithFormat:format arguments:args];
    va_end(args);
    
    fprintf(stdout, "%s\n", [string UTF8String]);
    
#if !__has_feature(objc_arc)
    [string release];
#endif
}

Now NSPrint() is like NSLog except that it prints the string to stdout without the garbage debug info:

NSPrint(@"Hello, %@.", myWorldString);

Why this isn't already part of Foundation is a mystery to me.