UTF-8字符串的大小(以字节为单位)

时间:2011-01-28 08:50:35

标签: c++ qt utf-8

我使用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个字节。

2 个答案:

答案 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