我正在从oracle数据库中读取可能包含或不包含Unicode字符的数据字符串到c ++程序中。是否有任何方法可以检查从数据库中提取的字符串是否包含Unicode字符(UTF-8)。如果存在任何Unicode字符,则应将其转换为十六进制格式并需要显示。
答案 0 :(得分:1)
这个问题有两个方面。
区分UTF-8编码的字符和普通的ASCII字符。
UTF-8将任何高于127的代码点编码为一系列两个或更多字节。 127及以下的值保持不变。来自编码的结果字节也高于127,因此检查字节的高位以查看它是否合格就足够了。
以十六进制显示编码字符。
C ++有std::hex
告诉流以十六进制格式化数值。您可以使用std::showbase
使输出看起来很漂亮。但是,char
不会被视为数字;流将只打印字符。您必须将值强制为其他数字类型,例如int
。但要注意签名扩展。
以下是一些要演示的代码:
#include <iostream>
void print_characters(char const* s)
{
std::cout << std::showbase << std::hex;
for (char const* pc = s; *pc; ++pc) {
if (*pc & 0x80)
std::cout << (*pc & 0xff);
else
std::cout << *pc;
std::cout << ' ';
}
std::cout << std::endl;
}
您可以这样称呼它:
int main()
{
char const* test = "ab\xef\xbb\xbfhu";
print_characters(test);
return 0;
}
使用Sun C ++ 5.8在Solaris 10上输出:
$ ./a.out a b 0xef 0xbb 0xbf h u
代码检测到UTF-8编码的字符,但它不会解码它们;你没有提到需要这样做。
我使用*pc & 0xff
将表达式转换为整数类型并屏蔽符号扩展位。没有它,我的计算机上的输出就是0xffffffbb
,例如。
答案 1 :(得分:0)
我会将字符串转换为UTF-32(您可以使用UTF CPP之类的东西 - 这很容易),然后遍历生成的字符串,检测高于0x7F的代码点(字符)并将它们打印为十六进制。