views:

61

answers:

2

I have this function:

void myFunc(NSString* data) {
    NSMutableArray *instrs = [[NSMutableArray alloc] initWithCapacity:[data length]];
    for (int i=0; i < [data length]; i++) {
        unichar c = [data characterAtIndex:i];
        [instrs addObject:c];
    }
    NSEnumerator *e = [instrs objectEnumerator];
    id inst;
    while (inst = [e nextObject]) {
        NSLog("%i\n", inst);
    }
}

I think it fails at [instrs addObject:c]. It's purpose is to iterate through the hexadecimal numbers of an NSString. What causes this code to fail?

+3  A: 

A unichar is not an object; it's an integer type.

NSMutableArray can only hold objects.

If you really want to put it into an NSMutableArray, you could wrap the integer value in an NSNumber object: [instrs addObject:[NSNumber numberWithInt:c]];

But, what's the point of stuffing the values into an array in the first place? You know how to iterate through the string and get the characters, why put them into an array just to iterate through them again?

Also note that:

  • the "%i" NSLog format expects an integer; you can't pass it an object
  • for hexadecimal output, you want "%x", not "%i"
David Gelhar
A: 

If the function is only meant to display the characters as hexadecimal values, you could use:

void myFunc(NSString* data)
{
    NSUInteger len = [data length];
    unichar *buffer = calloc(len, sizeof(unichar));

    if (!buffer) return;

    [data getCharacters:buffer range:NSMakeRange(0, len)];

    for (NSUInteger i = 0; i < len; i++)
        NSLog(@"%04x", (unsigned) buffer[i]);

    free(buffer);
}

This is just a little bit more efficient than your approach (also, in your approach you never release the instrs array, so it will leak in a non-garbage-collected environment).

If the string contains hexadecimal numbers, then you will want to repeatedly use an NSScanner's scanHexInt: method until it returns NO.

void myFunc(NSString* data)
{
    NSScanner *scanner = [[NSScanner alloc] initWithString:data];

    unsigned number;

    while ([scanner scanHexInt:&number])
        NSLog(@"%u", number);

    [scanner release];
}
dreamlax