char *与unsigned char *和cast

时间:2015-04-07 13:34:47

标签: c sqlite character-encoding

我需要使用SQLite函数sqlite3_prepare_v2()https://www.sqlite.org/c3ref/prepare.html)。

此函数将const char *作为其第二个参数。

另一方面,我准备了unsigned char *变量v,其中包含以下内容:

INSERT INTO t (c) VALUES ('amitié')

以十六进制表示(我剪切线):

49 4E 53 45 52 54 20 49 4E 54 4F 20 74 20 28 63 29
20 56 41 4C 55 45 53 20 28 27 61 6D 69 74 69 E9 27 29

请注意代表字符0xE9的{​​{1}}。

为了正确构建这段代码,当我将它作为参数传递给sqlite3_prepare_v2()函数时,我将变量év一起投射......

你对这个演员有什么评论?真的非常糟糕吗?

请注意,我一直使用(const char *)指针,只能在一个字节的unsigned char *0x00之间存储字符。

源数据来自ANSI编码文件。

0xFF函数的文档中,我还阅读了此函数的第二个参数的以下注释:

sqlite3_prepare_v2()

让我感到困扰的是函数第二个参数的/* SQL statement, UTF-8 encoded */ 类型......我本来期待const char *而不是......

对我来说 - 但是我可能完全错了 - 一个字符中只有7个有用的位(一个字节),最重要的位(最左边)用于表示字节的符号...

我想我在这里错过了某种观点......

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

你是对的。

对于UTF-8输入,sqlite3_prepare_v2方法确实应该要求const unsigned char *,因为所有8位都用于数据。它们的实现当然不应该使用带符号的比较来检查最高位,因为简单的编译器标志可以将char的默认值设置为unsignedsigned前者会打破代码。

至于你对演员的关注,这是一个更为温和的问题。在intfloat上删除签名通常是非常糟糕的事情(TM) - 或者至少是一个明确的指示您有问题。

当处理纯ASCII时,你是正确的,有7位数据,但剩下的第8位用于校验位,而不是用作符号位。