NSString * to Char[] (GameCenter Send Struct)

I want to send a struct to another player in GameCenter. I have read the other questions about this, however, I cannot get any of them to work.

I need to get @"1234" into a char[4] (ex char[0] = '1', char[1] = '2', etc)

I have tried [NSString UTF8String], but it doesn't seem to do what I want.

It assigns fine, but when I pull it back into NSString * with [NSString stringWithUTF8String:], It returns blank.

If someone could show me the conversion to and from, it would be greatly appreciated.

Thanks.

EDIT:

I can't get it to work :/ Here is my code (the abridged version):

Matchmaker.h

enum { NChars = 4 };

typedef struct {
    MessageType messageType;
} Message;

typedef struct {
    Message message;
    char code[NChars];
} MessageGameCode;

@interface Matchmaker : CCLayer <GameCenterMasterDelegate>{

    NSString *_code;
}
@property (nonatomic,retain) NSString *_code;

Matchmaker.m

@synthesize _code;
-(void)viewDidLoad{
    self._code = @"1234";
}

- (void)sendCode {
    NSLog(@"Sending Code....");
    MessageGameCode message;
    message.message.messageType = kMessageTypeGameCode;
    NSString * const source = self._code;

    const char* const sourceAsUTF8 = source.UTF8String;

    for (size_t idx = 0; idx < NChars; ++idx) {
        message.code[idx] = sourceAsUTF8[idx];
    }
    NSData *data = [NSData dataWithBytes:&message length:NChars];    
    [self sendData:data];
}

- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID {
    Message *message = (Message *) [data bytes];
    if (message->messageType == kMessageTypeGameCode) {        

        MessageGameCode *codeMessage = (MessageGameCode *)[data bytes];
        self._code = [[NSString alloc] initWithBytes:codeMessage->code length:NChars encoding:NSUTF8StringEncoding];
        [self setGameState:kGameStateWaitingForStart];
        NSLog(@"Game Code Recieved");
        NSLog(@"Recieved Code: %@",self._code); //This always shows self._code as blank

    }
}

Upvotes: 0

Views: 623

Answers (3)

justin
justin

Reputation: 104698

Your attempt will fail because the cstring which you pass to + [NSString stringWithUTF8String:] is not terminated.

Try this:

NSString * result = [[NSString alloc] initWithBytes:bytes
                                             length:4
                                           encoding:NSUTF8StringEncoding];

Edit

A more complete demonstration:

enum { NChars = 4 };
/* requires error checking */
void transmit() {
    NSString * const source = @"1234";

    char tmp[NChars] = { 0 };
    const char* const sourceAsUTF8 = source.UTF8String;

    for (size_t idx = 0; idx < NChars; ++idx) {
      tmp[idx] = sourceAsUTF8[idx];
    }
    /* .. */
}

/* requires error checking */
void receive(const char bytes[NChars]) {
    NSString * result = [[NSString alloc] initWithBytes:bytes length:NChars encoding:NSUTF8StringEncoding];
    /* ... */
}

Upvotes: 7

David Gelhar
David Gelhar

Reputation: 27900

There are a couple of possible pitfalls here.

One is that with [NSString UTF8String] "The returned C string is automatically freed just as a returned object would be released; you should copy the C string if it needs to store it outside of the autorelease context in which the C string is created.". So, depending on how long you're expecting the value to stick around you may need to copy it (for example, using strcpy)

The other issue is that [NSString UTF8String] and [NSString stringWithUTF8String:] both expect NULL-terminated C strings, so you need a char[5], not a char[4] to hold @"1234".

Upvotes: 1

JeremyP
JeremyP

Reputation: 86651

One way is

char bytes[4];

NSData* data = [@"1234" dataUsingEncoding: NSUTF8StringEncoding];
if ([data length] <= 4)
{
    memcpy(bytes, [data bytes], [data length]);
}

And to go the other way:

NSString* recodedString = [[NSString alloc] initWithBytes: bytes 
                                                   length: savedLengthFromBefore 
                                                 encoding: NSUTF8StringEncoding];

Upvotes: 1

Related Questions