【发布时间】:2015-08-03 11:21:23
【问题描述】:
在从站点加载一些 html 并将其保存到数据库之间的某个地方,字符被省略或更改为奇怪的东西时遇到了麻烦。流程如下:
用libcurl加载站点,这是write函数的内容:
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}
网站在 html 中设置了 utf8 作为编码类型。
字符串保留为 std::string,然后传递到 Mysql cppconn 以输入到数据库表中。
表的排序规则设置为 utf8_unicode_ci,相关字段也是如此。
但是当我在Adminer中查看表格内容时,字段中的文字已经被截断,只显示了前半部分文字,只是困难字符(é)之前的普通字符。
我注意到的一件事是,在整个程序的 cout 输出中,é 从未正确显示,而是在菱形符号中显示问号。终端设置为当前语言环境:UTF-8。
这让我想,也许我从 libcurl 得到的实际上并不是 utf-8,所以我使用 boost 库尝试将其更改为 utf-8,使用:
std::locale loc("");
std::locale conv_loc = boost::locale::util::create_info(loc, loc.name());
std::string output = boost::locale::conv::to_utf<char>(codepage_str, conv_loc);
我尝试将它放在上面粘贴的 write 函数中的 return 之前,但效果是它只是从文本中删除了有问题的字符。
我在这里俯瞰什么?
现在已经输出了有问题的名称及其 utf8 值,但对我有什么帮助?
Cuauht�moc Ruelas - 0x43 0x75 0x61 0x75 0x68 0x74 0xffffffe9 0x6d 0x6f 0x63 0x20 0x52 0x75 0x65 0x6c 0x61 0x73
【问题讨论】:
-
字符所在字符串中的实际 (utf-8) 值是多少?它是否符合 UTF-8 定义的字符代码点?这是你应该检查的第一件事——不要使用 cout (除非你输出字符的整数值)。您应该逐个字节地检查每个字符串,以确保字符串是正确的,从源字符串开始(跟踪它并注意断开连接发生的位置)。
-
如何检查字符所在字符串中实际的 utf-8 值是多少?
-
for (auto ch : string_value) std::cout << std;:hex << std::setw(2) << std::showbase << static_cast<int>(ch) << " ";,例如 -
@GemmaB89 基本上,您使用错误的工具来诊断问题。您应该(如先前的评论所建议的那样)逐个倾倒字符值。如果不是这样,在您的调试器中,检查字符串不是“std::string”,而是获取指向实际缓冲区的指针并查看内存。使用诸如
cout << std::string之类的“高级”例程的问题是,您可能会完全错过控制台(或调试器)可能会屏蔽的任何字符。 -
这是有道理的,对不起,这很新,这是输出:Cuauht�moc Ruelas - 0x43 0x75 0x61 0x75 0x68 0x74 0xffffffe9 0x6d 0x6f 0x63 0x20 0x52 0x75 0x65 0x6c 0x61 07>
标签: c++ mysql boost utf-8 character-encoding