How to convert an NSString to char

2019-09-19 02:51发布

问题:

I am trying to convert an NSString to a ResType, as defined below in MacTypes.h.

FourCharCode // A 32-bit value made by packing four 1 byte characters together
typedef FourCharCode ResType;

I think I could use [aString getCharacters:range:], but is there a more straight forward way to make this conversion?

After trying suggestions from David, here is some further information.

I am using GTResourceFork, a Cocoa wrapper for accessing resource forks. The method I am calling is: - (NSArray *)usedResourcesOfType: (ResType)type;

If I hard code a value of 'RTF ', I get the results I expect. I cannot figure out how to convert an NSString containing "RTF " to the hard-coded value. I created a test case using NSString's getCharacters and getBytes, and they all give me different integer values. How can I convert the NSString to give me the same integer value as the hard-coded one?

 Method used:       Value:  Casted int value:
 Hard Coded(Works): 'RTF ' '1381254688'
 getCharacters:     'RTF ' '5505106'
 getBytes(ASCII):   'RTF ' '541480018'
 getBytes(UTF8):    'RTF ' '541480018'

Thanks in advance, Lance

回答1:

The problem with getCharacters:range: is that it gives you UTF-16 characters (unichars), whereas you want ASCII.

*(ResType*)[aString UTF8String] will convert the string to UTF-8 (which is equivalent to ASCII as long as all the characters in the string fit within the ASCII range) and then give you the first four bytes as a ResType value. Whether this is efficient enough depends on how often you want to do these conversions.

Another option is to use getBytes:maxLength:usedLength:encoding:options:range:remainingRange: with the encoding set to NSASCIIStringEncoding or NSUTF8StringEncoding, the destination buffer set to a pointer to an existing ResType variable, and the maximum length set to 4 (or sizeof (ResType)).


Update:

I've figured out why you're not getting the correct result with my suggestion. It turns out that in four-character integer literals, the bytes are stored in the opposite order to how they're written. Here's an example:

#include <Foundation/Foundation.h>

int main() {
    int code = 'RTF ';
    printf("'%c%c%c%c' = %d\n", ((char*)&code)[0], ((char*)&code)[1],
                                ((char*)&code)[2], ((char*)&code)[3],
                                code);
}

The output is ' FTR' = 1381254688. So, if you want to convert from NSStrings to these values, here are a few options:

  • Copy the string into a four-byte buffer (using one of the methods I suggested) and then reverse it by swapping byte 0 with byte 3, and byte 1 with byte 2.
  • The same, but do the reversing using a standard "endianness-swapping" algorithm like the one on this page.
  • Iterate through first (and only) four characters using characterAtIndex:, and insert them into a four-byte buffer in reverse. Remember that characterAtIndex: returns a UTF-16 character, but this can be easily cast to as ASCII character assuming it is within the ASCII range.