我使用QString存储字符串,现在我需要在POD结构中存储这些字符串(转换为UTF-8编码),如下所示:
template < int N >
struct StringWrapper
{
char theString[N];
};
要从QString转换原始数据,我这样做:
QString str1( "abc" );
StringWrapper< 20 > str2;
strcpy( str2.theString, str1.toUtf8().constData() );
现在的问题。我注意到如果我从普通字符串转换,它可以正常工作:
QString str( "abc" );
std::cout<< std::string( str.toUtf8().constData() ) << std::endl;
将产生输出:
abc
但如果我使用一些特殊字符,例如:
QString str( "Schöne Grüße" );
std::cout<< std::string( str.toUtf8().constData() ) << std::endl;
我得到这样的垃圾:
Gr\xC3\x83\xC2\xBC\xC3\x83\xC2\x9F
我显然错过了什么,但究竟出了什么问题呢?
其他问题
UTF-8编码字符的最大大小是多少?我读了它here它是4个字节。
答案 0 :(得分:3)
您需要回答的第一个问题是源文件的编码是什么?除非使用QTextStream :: setCodecForCStrings()更改它,否则QString默认构造函数假定它是Latin1。因此,如果你的来源不是Latin1(比如说UTF-8),那么你得到的结果是错误的:
QString str( "Schöne Grüße" );
现在,如果您的来源是UTF-8,则需要将其替换为:
QString str = QString::fromUtf8( "Schöne Grüße" );
或者,更好的是,尽可能使用QObject :: trUf8(),因为它为您提供i18n功能作为免费奖励。
接下来要检查的是控制台的编码是什么。您尝试打印UTF-8字符串,但它是否支持UTF-8?如果它是Windows控制台,它可能不是。如果在具有* .UTF-8语言环境的* nix系统上使用Unicode字体的xterm兼容,那应该没问题。
致编辑问题:
我认为没有任何理由不相信维基百科,特别是当它涉及特定标准时。它还提到UTF-8曾经有多达6个字节的字符。根据我的经验,使用合理的母语字符(如拉丁语/西里尔语/希伯来语/中文/日语)可获得3个字节。 4个字节可能用于更具异国情调的东西,如果你真的很好奇,你可以随时查看标准。
答案 1 :(得分:1)
首先出现的问题是你所说的假设。 QString
不存储UTF-8,它存储unicode字符串。这就是你需要致电str1.toUtf8()
的原因。它会创建一个临时的UTF-8字符串。
第二部分是UTF-8的工作原理。它是ASCII的多字节扩展。 üß
不是ASCII字符,并且您确实希望两个字符都获得多字节表示。 std::cout
显然不期望UTF-8。这取决于使用的std::locale
。