Kurt Peek
Kurt Peek

Reputation: 57381

How to use NSString's writeToFile method

I'm trying to write an Objective-C program which writes all knownTimeZoneNames to a file. So far I've tried:

#import <Foundation/Foundation.h>

int main(void) {
    [[NSFileManager defaultManager] createFileAtPath:@"knownTimeZoneNames.txt" contents:nil attributes:nil];


    for (NSString *name in [NSTimeZone knownTimeZoneNames]) {
        [name writeToFile:"knownTimeZoneNames.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
//      NSLog(@"The time zone is %@", name);

    }
    return 0;
}

Note that if I comment in the line with NSLog and comment out the one with writeToFile, the program prints the expected output. As it is, however, I get warnings about incompatible pointer types:

write_known_timezone_names.m: In function ‘main’:
write_known_timezone_names.m:10:3: warning: passing argument 1 of ‘writeToFile:atomically:encoding:error:’ from incompatible pointer type [-Wincompatible-pointer-types]
   [name writeToFile:"knownTimeZoneNames.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
   ^
write_known_timezone_names.m:10:3: note: expected ‘struct NSString *’ but argument is of type ‘char *’
write_known_timezone_names.m:10:3: warning: passing argument 4 of ‘writeToFile:atomically:encoding:error:’ from incompatible pointer type [-Wincompatible-pointer-types]
write_known_timezone_names.m:10:3: note: expected ‘struct NSError **’ but argument is of type ‘id’
The file write_known_timezone_names.m has been compiled and can be run using the command ./write_known_timezone_names.

and if I try to run the program I get a Segmentation fault:

2017-02-03 12:31:49.485 write_known_timezone_names[23626] autorelease called without pool for object (0x17d6f90) of class NSDataStatic in thread <NSThread: 0x175e330>
2017-02-03 12:31:49.487 write_known_timezone_names[23626] autorelease called without pool for object (0x18e4f70) of class NSMutableDataMalloc in thread <NSThread: 0x175e330>
2017-02-03 12:31:49.489 write_known_timezone_names[23626] autorelease called without pool for object (0x18ec110) of class NSDataMalloc in thread <NSThread: 0x175e330>
Segmentation fault (core dumped)

How can I fix this program?

Upvotes: 0

Views: 1419

Answers (4)

Inder Kumar Rathore
Inder Kumar Rathore

Reputation: 39978

int main(void) {
 [[NSFileManager defaultManager] createFileAtPath:@"knownTimeZoneNames.txt" contents:nil attributes:nil];

NSMutableString *timeZones = [[NSMutableString alloc] init];
for (NSString *name in [NSTimeZone knownTimeZoneNames]) {
    [timeZones appendFormat:@"%@\n", name];    
}
[timeZones writeToFile:@"knownTimeZoneNames.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];

return 0;
}

Upvotes: 2

vadian
vadian

Reputation: 285039

  1. Regarding Segmentation fault: As the error message autorelease called without pool reveals you have to wrap the code in an autorelease pool

    @autoreleasepool {
    
        [[NSFileManager defaultManager] createFileAtPath:@"knownTimeZoneNames.txt" contents:nil attributes:nil];
    
        for (NSString *name in [NSTimeZone knownTimeZoneNames]) {
            [name writeToFile:@"knownTimeZoneNames.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
            //NSLog(@"The time zone is %@", name);
        }
        return 0;
    }
    
  2. I don't know where you want to write the file but a path must start with a slash and in iOS you have to get programmatically one of the directories you have permission to write into.
  3. And even if the other issues are resolved your resulting text file will contain just one line (the name of the last iteration). To get all names – one per line – use this instead of the repeat loop

    NSArray *nameArray = [NSTimeZone knownTimeZoneNames];
    NSString *names = [nameArray componentsJoinedByString:@"\n"];
    

Upvotes: 3

firstinq
firstinq

Reputation: 782

You missed @ before filename. Correct code:

int main(void) {
 [[NSFileManager defaultManager] createFileAtPath:@"knownTimeZoneNames.txt" contents:nil attributes:nil];


for (NSString *name in [NSTimeZone knownTimeZoneNames]) {
    [name writeToFile:@"knownTimeZoneNames.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
    //      NSLog(@"The time zone is %@", name);

}
return 0;}

Upvotes: 3

AVerguno
AVerguno

Reputation: 1377

Please, try this

for (NSString *name in [NSTimeZone knownTimeZoneNames]) {
     // You was trying to pass chars, but you have to pass string.   
    [name writeToFile:@"knownTimeZoneNames.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
    //      NSLog(@"The time zone is %@", name);
}

Upvotes: 1

Related Questions