遍历包含“扩展 ASCII”字符的 const unsigned char *
Posted
技术标签:
【中文标题】遍历包含“扩展 ASCII”字符的 const unsigned char *【英文标题】:Iterating through const unsigned char * containing "Extended ASCII" characters 【发布时间】:2013-06-18 01:26:07 【问题描述】:在我的 iPhone 应用程序的 sqlite 数据库中,我使用扩展的 ASCII 字符集将一个长整数数组(最多 5 位)编码/压缩为一个字符串,以将其缩减为 2 个字符。 (换句话说,我使用base150对其进行编码)
当从数据库中取出它时,sqlite3_column_text() 将字符串作为“const unsigned char *”返回。我可以使用 printf 正确打印此字符串(它甚至可以正确显示超过 128 的 ASCII 字符)但是当我尝试遍历它并单独访问字符串的每个字符以转换回我的整数时,ASCII 值超过 128 的字符会失败,因为它们是多字节的,而且它只有一个字节(我认为)。
例子:
我有一个名为 encodedString 的字符串,其中包含:svÖ)
unsigned char c = encodedString[0];
unsigned char d = encodedString[2];
printf("%c", c); //outputs "s"
printf("%c", d); //outputs "\303"
printf("%s", encodedString); //outputs "svÖ)"
我也尝试过 wchar_t,结果相同。我已经使用 NSStrings 让它工作,但它非常慢,而且我这样做了数千次(根据分析器,NSMakeRange 是罪魁祸首),所以我希望它尽可能快,因此 C.
从字符串中获取单个多字节/扩展 ASCII 字符的技巧是什么?
【问题讨论】:
从中创建一个 NSString。这是重建它的最简单方法。它不应该那么慢。你是如何建造它们的?据我所知,ASCII 从来都不是多字节的。但是,您指出的字符似乎不是 ASCII。它看起来是 unicode 组合波浪号。 我正在尝试使用扩展的 ASCII 集,如 here 所示。当我执行从 0 到 255 的 for 循环并将 int 转换为 char 时,我的输出与该表匹配(我上面的奇怪字符是 153)。换句话说,如果我将 unsigned char 硬编码到该字符,它会正确保存并显示它。只是当它被放入一个字符串时,我基本上无法将它恢复原样。我确实使用了 NSString,并且使用 NSMakeRange 来获取单个字符是一个瓶颈。性能无法接受。 我不明白你会用 NSMakeRange 做什么。为什么不直接使用[[NSString alloc] initWithCString:encoding:]
使用NSISOLatin1StringEncoding
将整个东西变成一个NSString 呢?
P.S.如果你只使用 2 个字符,你是如何使用 unsigned char d = encodedString[2];
的?
你不能,因为它们不是你所期望的字符,而且它们不再是单字节的。您期待“153”(0x99),但您将得到的是“195 150”(0xC3 0x96)。这就是为什么我说你需要展示你是如何制作这个字符串值的。我质疑你所做的事情的有效性。扩展的 ASCII 远非标准。
【参考方案1】:
我建议不要使用TEXT
列,而是使用BLOB
列,其中数据包含您想要使用的任何大小的整数数组(可能是16 位无符号数)。
您可以使用sqlite_column_bytes()
来确定列的大小,从而允许使用可变长度的列。
这将避免您当前面临的复杂性。
【讨论】:
以上是关于遍历包含“扩展 ASCII”字符的 const unsigned char *的主要内容,如果未能解决你的问题,请参考以下文章