Юникод — c ++ литерал u8 и BOM (маска байтов)

Я решил написать простой пример:

#include <iostream>

int main()
{
std::cout << u8"это строка6" << std::endl;
return 0;
}

Выполнил в консоли следующую команду:
ЧКП 65001

Выход программы:

��то строка6

Почему первый символ отображается неправильно? Я думаю, что кодовая страница 65001 использует спецификацию и считывает первый символ как спецификацию. Это правда?

1

Решение

Ну, вся стандартная библиотека ввода-вывода хитрая с этой кодовой страницей. Вот еще одна тестовая программа (\xe2\x86\x92 это стрелка в UTF-8):

#include <stdio.h>

int main(void)
{
char s[] = "\xe2\x86\x92 a \xe2\x86\x92 b\n";
int l = (int) sizeof(s) - 1;
int wr = fwrite(s, 1, l, stdout);
printf("%d/%d written\n", wr, l);
return 0;
}

И его вывод:

��� a → b
10/12 written

Обратите внимание, что первый символ снова заменяется ��� (это 3 байта в UTF-8), а fwrite вызов возвращает номер персонажи написано на консоли. Это нарушение стандарта C (должно возвращаться число байтов), и он будет корректно разбивать каждую программу, использующую fwrite или связанные функции (например, попытаться напечатать "☺☺☺☺☺☺☺☺☺☺☺☺" с Python 3.4).

Таким образом, ваши единственные варианты надежного вывода текста Unicode зависят от Windows (если только эти проблемы не исправлены в последней версии MSVC):

2

Другие решения