Что нужно знать:
- страница символов выполнения
В стандарте C ++ есть нечто, называемое выполнение набором символов, который является термином, который описываетчто будет выводить строковые и символьные литералы в двоичном коде, создаваемом компилятором.Вы можете прочитать об этом в подразделе 1.1 Наборы символов в разделе 1 Overview в Руководство препроцессора C на http://gcc.gnu.org сайте.
Вопрос:
Что будет получено в результате "\u00fc"
строкового литерала?
Ответ:
Это зависит от того, какой набор символов выполнения.В случае gcc (который вы используете) это по умолчанию UTF-8, если вы не укажете что-то другое с опцией -fexec-charset
.Вы можете прочитать об этой и других опциях, управляющих фазой предварительной обработки, в разделе 3.11 Опции Управление препроцессором в разделе 3 Опции команды GCC в Руководстве GCC в http://gcc.gnu.org сайт.Теперь, когда мы знаем, что набор символов выполнения - UTF-8, мы знаем, что "\u00fc"
будет преобразовано в кодировку UTF-8 U+00FC
кодовой точки Unicode, которая представляет собой последовательность из двух байтов 0xc3 0xbc
.
Конструктор QString, принимающий char *
, вызывает QString QString::fromAscii ( const char * str, int size = -1 )
, который использует кодек, установленный с помощью void QTextCodec::setCodecForCStrings ( QTextCodec * codec )
(если был установлен какой-либо кодек) или выполняет те же действия, что и QString QString::fromLatin1 ( const char * str, int size = -1 )
(если кодек не был установлен).
Вопрос:
Какой кодек будет использоваться конструктором QString для декодирования двухбайтовой последовательности (0xc3 0xbc
), которую он получает?
Ответ:
По умолчанию кодек не установлен с QTextCodec::setCodecForCStrings()
, поэтому Latin1 будет использоваться для декодирования последовательности байтов.Поскольку 0xc3
и 0xbc
действительны на латинице 1, представляющие соответственно Ã и ¼ (это должно быть вам уже знакомо, поскольку оно было взято непосредственно из этого ответа на ваш предыдущий вопрос), мы получаем QStringс этими двумя символами.
Вы не должны использовать класс QDebug
для вывода чего-либоза пределами ASCII .У вас нет гарантии, что вы получите.
Тестовая программа:
#include <QtCore>
void dbg(char const * rawInput, QString s) {
QString codepoints;
foreach(QChar chr, s) {
codepoints.append(QString::number(chr.unicode(), 16)).append(" ");
}
qDebug() << "Input: " << rawInput
<< ", "
<< "Unicode codepoints: " << codepoints;
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
qDebug() << "system name:"
<< QLocale::system().name();
for (int i = 1; i <= 5; ++i) {
switch(i) {
case 1:
qDebug() << "\nWithout codecForCStrings (default is Latin1)\n";
break;
case 2:
qDebug() << "\nWith codecForCStrings set to UTF-8\n";
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
break;
case 3:
qDebug() << "\nWithout codecForCStrings (default is Latin1), with codecForLocale set to UTF-8\n";
QTextCodec::setCodecForCStrings(0);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
break;
case 4:
qDebug() << "\nWithout codecForCStrings (default is Latin1), with codecForLocale set to Latin1\n";
QTextCodec::setCodecForCStrings(0);
QTextCodec::setCodecForLocale(QTextCodec::codecForName("Latin1"));
break;
}
qDebug() << "codecForCStrings:" << (QTextCodec::codecForCStrings()
? QTextCodec::codecForCStrings()->name()
: "NOT SET");
qDebug() << "codecForLocale:" << (QTextCodec::codecForLocale()
? QTextCodec::codecForLocale()->name()
: "NOT SET");
qDebug() << "\n1. Using QString::QString(char const *)";
dbg("\\u00fc", QString("\u00fc"));
dbg("\\xc3\\xbc", QString("\xc3\xbc"));
dbg("LATIN SMALL LETTER U WITH DIAERESIS", QString("ü"));
qDebug() << "\n2. Using QString::fromUtf8(char const *)";
dbg("\\u00fc", QString::fromUtf8("\u00fc"));
dbg("\\xc3\\xbc", QString::fromUtf8("\xc3\xbc"));
dbg("LATIN SMALL LETTER U WITH DIAERESIS", QString::fromUtf8("ü"));
qDebug() << "\n3. Using QString::fromLocal8Bit(char const *)";
dbg("\\u00fc", QString::fromLocal8Bit("\u00fc"));
dbg("\\xc3\\xbc", QString::fromLocal8Bit("\xc3\xbc"));
dbg("LATIN SMALL LETTER U WITH DIAERESIS", QString::fromLocal8Bit("ü"));
}
return app.exec();
}
Вывод на mingw 4.4.0 в Windows XP:
system name: "pl_PL"
Without codecForCStrings (default is Latin1)
codecForCStrings: "NOT SET"
codecForLocale: "System"
1. Using QString::QString(char const *)
Input: \u00fc , Unicode codepoints: "c3 bc "
Input: \xc3\xbc , Unicode codepoints: "c3 bc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fc "
2. Using QString::fromUtf8(char const *)
Input: \u00fc , Unicode codepoints: "fc "
Input: \xc3\xbc , Unicode codepoints: "fc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fffd "
3. Using QString::fromLocal8Bit(char const *)
Input: \u00fc , Unicode codepoints: "102 13d "
Input: \xc3\xbc , Unicode codepoints: "102 13d "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fc "
With codecForCStrings set to UTF-8
codecForCStrings: "UTF-8"
codecForLocale: "System"
1. Using QString::QString(char const *)
Input: \u00fc , Unicode codepoints: "fc "
Input: \xc3\xbc , Unicode codepoints: "fc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fffd "
2. Using QString::fromUtf8(char const *)
Input: \u00fc , Unicode codepoints: "fc "
Input: \xc3\xbc , Unicode codepoints: "fc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fffd "
3. Using QString::fromLocal8Bit(char const *)
Input: \u00fc , Unicode codepoints: "102 13d "
Input: \xc3\xbc , Unicode codepoints: "102 13d "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fc "
Without codecForCStrings (default is Latin1), with codecForLocale set to UTF-8
codecForCStrings: "NOT SET"
codecForLocale: "UTF-8"
1. Using QString::QString(char const *)
Input: \u00fc , Unicode codepoints: "c3 bc "
Input: \xc3\xbc , Unicode codepoints: "c3 bc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fc "
2. Using QString::fromUtf8(char const *)
Input: \u00fc , Unicode codepoints: "fc "
Input: \xc3\xbc , Unicode codepoints: "fc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fffd "
3. Using QString::fromLocal8Bit(char const *)
Input: \u00fc , Unicode codepoints: "fc "
Input: \xc3\xbc , Unicode codepoints: "fc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fffd "
Without codecForCStrings (default is Latin1), with codecForLocale set to Latin1
codecForCStrings: "NOT SET"
codecForLocale: "ISO-8859-1"
1. Using QString::QString(char const *)
Input: \u00fc , Unicode codepoints: "c3 bc "
Input: \xc3\xbc , Unicode codepoints: "c3 bc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fc "
2. Using QString::fromUtf8(char const *)
Input: \u00fc , Unicode codepoints: "fc "
Input: \xc3\xbc , Unicode codepoints: "fc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fffd "
3. Using QString::fromLocal8Bit(char const *)
Input: \u00fc , Unicode codepoints: "c3 bc "
Input: \xc3\xbc , Unicode codepoints: "c3 bc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fc "
codecForCStrings: "NOT SET"
codecForLocale: "ISO-8859-1"
1. Using QString::QString(char const *)
Input: \u00fc , Unicode codepoints: "c3 bc "
Input: \xc3\xbc , Unicode codepoints: "c3 bc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fc "
2. Using QString::fromUtf8(char const *)
Input: \u00fc , Unicode codepoints: "fc "
Input: \xc3\xbc , Unicode codepoints: "fc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fffd "
3. Using QString::fromLocal8Bit(char const *)
Input: \u00fc , Unicode codepoints: "c3 bc "
Input: \xc3\xbc , Unicode codepoints: "c3 bc "
Input: LATIN SMALL LETTER U WITH DIAERESIS , Unicode codepoints: "fc "
Я бы хотелспасибо thiago , cbreak , peppe и heinz с IRC-канала #qt freenode.org за то, что они показали и помогли мне разобраться в проблемах, возникающих здесь.