在 iOS 项目中 NSString 和 C 字符串之间的转换





5.00/5 (1投票)
如何在 iOS 项目中转换 NSString 和 C 字符串
我最近需要在 iOS 项目中使用一个 C 库,该项目主要使用 Objective-C。 一切进展顺利,直到我遇到一些返回 C 字符串
(wchar_t*
、char*
)并且需要进行转换才能与 Objective-C NSString*
类型一起工作的 C 函数。
在 xCode 的 iOS 项目中,声明 字符串
有三种方法
NSString* str = @”hello world”; // declare an Objective-C string
wchar_t* str = L”hello world”; // declare a wide-character (Unicode) string
char* str = “hello world”; // declare an ANSI string
如果你使用 L”” 语法声明 Unicode 字符串
,编译器默认使用 UTF32。 如果输入字符串不是 UTF8 编码,则函数 wcslen()
获取 字符串
的长度(例如,字符数)可能无法正常工作。 例如,尝试以下代码
wchar_t* str1 = L”Giới thiệu về Google”; // “About Google” in Vietnamese
wchar_t* str2 = L”Gioi thieu ve Google”; // simplified with ANSI characters only
printf(“str1 length: %d”, wcslen(str1));
printf(“str2 length: %d”, wcslen(str2));
该代码将为 str1
输出错误的长度,为 str2
输出正确的长度,即使它们具有相同的字符数。 我认为 wcslen
对 str1
中的 UTF32 字符感到困惑,并多次计算某些字符。 但是,如果我尝试以下代码
char* str3 = “Giới thiệu về Google”;
setlocale(LC_ALL, “en_US.UTF-8″);
int buflen = strlen(str3)+1;
wchar_t* buffer = malloc(buflen * sizeof(wchar_t));
mbstowcs(buffer, str3, buflen);
printf(“str3 length: %d”, wcslen(str3));
free(buffer);
声明一个 ANSI 字符串
并使用 setlocale
转换为 UTF8 宽 字符串
,以确保正确的 Unicode 编码,则 wcslen
将返回正确的 字符串
长度。 不知道问题是什么,我必须确保项目中的所有 C 字符串
都是 UTF8 编码的。
使用内置的 NSUTF8StringEncoding
方法,将 NSString*
转换为 ANSI 字符串
(char*
)非常容易。 只要原始值有效,返回的值就是有效的,因此无需释放或释放它。 以下方法(来自我的自定义 NSString
分类)显示了如何实现这一点
- (const char*)getMultiByteString
{
return [self cStringUsingEncoding:NSUTF8StringEncoding];
}
使用 C 函数 mbstowcs
将 NSString*
转换为宽 字符串
(wchar_t*
)则要复杂一些
- (wchar_t*)getWideString
{
const char* temp = [self cStringUsingEncoding:NSUTF8StringEncoding];
int buflen = strlen(temp)+1; //including NULL terminating char
wchar_t* buffer = malloc(buflen * sizeof(wchar_t));
mbstowcs(buffer, temp, buflen);
return buffer;
}
调用者有责任释放返回的缓冲区。 为了改进,可以在 NSString
的 dealloc()
方法中释放返回值。 然后应将返回类型更改为 const wchar_t*
,以指示返回的值是只读的。
请注意,wchar_t
在 Windows 上为 2 个字节,但在 Unix/Linux(包括 iOS)上为 4 个字节。 上述函数使用 sizeof
来确定 wchar_t
的大小,以求通用性。
使用 stringWithUTF8String
和 wcstombs
,我们可以反过来执行操作,将 C 字符串
转换为 NSString
+ (NSString*)stringWithWideString:(const wchar_t*)ws
{
// Destination char array must allocate more than just wcslen(ws)
// since unicode chars may consume more than 1 byte
// we do not yet know how many bytes the created array may consume, so assume the max.
int bufflen = 8*wcslen(ws)+1;
char* temp = malloc(bufflen);
wcstombs(temp, ws, bufflen);
NSString* retVal = [self stringWithUTF8String:temp];
free(temp);
return retVal;
}
我希望这能帮助其他遇到类似问题的人。