c ++, cout и UTF-8 - PullRequest
       24

c ++, cout и UTF-8

8 голосов
/ 05 августа 2011

Надеюсь, простой вопрос: cout, кажется, умирает при обработке строк, заканчивающихся многобайтовым символом UTF-8, я что-то не так делаю? Это с GCC (Mingw) на Win7 x64.

** Edit Извините, если я не был достаточно ясен, меня не беспокоят пропущенные глифы или то, как интерпретируются байты, просто то, что они вообще не отображаются сразу после вызова cout << s4 (отсутствует BAR ). Дальнейшие cout с после первого отображения без текста вообще!

#include <cstdio>
#include <iostream>
#include <string>

int main() {
    std::string s1("abc");
    std::string s2("…");  // … = 0xE2 80 A6
    std::string s3("…abc");
    std::string s4("abc…");

    //In C
    fwrite(s1.c_str(), s1.size(), 1, stdout);
    printf(" FOO ");
    fwrite(s2.c_str(), s2.size(), 1, stdout);
    printf(" BAR ");
    fwrite(s3.c_str(), s3.size(), 1, stdout);
    printf(" FOO ");
    fwrite(s4.c_str(), s4.size(), 1, stdout);
    printf(" BAR\n\n"); 

    //C++
    std::cout << s1 << " FOO " << s2 << " BAR " << s3 << " FOO " << s4 << " BAR ";
}

// results:

// abc FOO ��� BAR ���abc FOO abc… BAR

// abc FOO ��� BAR ���abc FOO abc…

Ответы [ 4 ]

4 голосов
/ 05 августа 2011

Если вы хотите, чтобы ваша программа использовала ваш текущий язык, сначала наберите setlocale(LC_ALL, "") в вашей программе.В противном случае языковой стандарт программы C, и то, что она будет делать с не-ASCII-символами, неизвестно нам, простым людям.

2 голосов
/ 05 августа 2011

Это действительно не удивительно.Если ваш терминал не настроен на кодировку UTF-8, как он узнает, что s2 не должно быть "(латинская строчная буква a с круговым выражением) (знак евро) (труба)", предполагая, что ваш терминал установленISO-8859-1 в соответствии с http://www.ascii -code.com /

Кстати, cout не «умирает», поскольку он явно продолжает производить вывод после вашей тестовой строки.

0 голосов
/ 05 августа 2011

Как уже отмечали другие, std::cout не зависит от этого, по крайней мере, в "C" локали (по умолчанию). С другой стороны, ваше окно консоли должно быть настроено на отображение UTF-8: кодовая страница 65001. Попробуйте вызвать chcp 65001 перед выполнением вашей программы. (Это работало для меня в прошлом.)

0 голосов
/ 05 августа 2011

Консоль Windows по умолчанию не обрабатывает символы нелокальной кодовой страницы.

Вам необходимо убедиться, что в окне консоли установлен шрифт с поддержкой Unicode, и что кодовая страница установлена ​​в UTF-8 посредством вызова chcp. Это не гарантированный успех, хотя. Обратите внимание, что wcout ничего не меняет, если консоль не может отображать причудливые символы, потому что ее шрифт испорчен.

На всех современных дистрибутивах Linux консоль настроена на UTF-8, и это должно работать "из коробки".

...