Оптимизация последнего вызова может саботироваться не вызов хвоста. В языке Common LISP:
(defun f () (1+ (f)))
Прежде чем идти дальше, я должен упомянуть, что то, что вы делаете, не совместимо с c / c ++. В спецификации указано в 2.2, какие наборы символов допустимы в исходном коде. Там немного, и все используемые символы находятся в ascii. Итак ... Все, что ниже, касается конкретной реализации (как оказалось, VC2008 на машине с локалью США).
Для начала у вас есть 4 символа в строке cout
и 4 символа на выход. Таким образом, проблема заключается не в кодировке UTF8, поскольку она объединяет несколько исходных символов с меньшим количеством глифов.
От исходной строки до отображения на консоли все эти вещи играют свою роль:
<<
интерпретирует закодированную строку, которую вы передаете Теперь ...
1 и 2 довольно простые. Похоже, что компилятор угадывает, в каком формате находится исходный файл, и декодирует его во внутреннее представление. Он генерирует соответствующий блок данных строкового литерала в текущей кодовой странице независимо от исходной кодировки. Я не смог найти явных подробностей / контроля по этому поводу.
3 еще проще. За исключением управляющих кодов, <<
просто передает данные для char *.
4 управляется SetConsoleOutputCP
. Он должен по умолчанию использовать вашу системную кодовую страницу по умолчанию. Вы также можете определить, какой у вас есть, с помощью GetConsoleOutputCP
(вводом управляют по-другому, через SetConsoleCP
)
5 - забавный вариант. Я ударил головой, пытаясь понять, почему я не могу заставить é правильно отображаться, используя CP1252 (западноевропейский, windows). Оказывается, мой системный шрифт не имеет глифа для этого символа и услужливо использует глиф моей стандартной кодовой страницы (заглавная Theta, то же самое, что я получил бы, если бы не вызвал SetConsoleOutputCP). Чтобы исправить это, мне пришлось изменить шрифт, который я использую на консолях, на Lucida Console (настоящий шрифт).
Некоторые интересные вещи, которые я узнал, глядя на это:
233 0
) Итак ... что это для вас значит? Вот несколько советов:
char * a = "é"; std :: cout << (unsigned int) (unsigned char) a [0]
действительно показывает 233 для меня, что является кодировкой в CP1252. Я пробовал этот код:
#include <iostream>
#include <fstream>
#include <sstream>
int main()
{
std::wstringstream wss;
wss << L"àéêù";
std::wstring s = wss.str();
const wchar_t* p = s.c_str();
std::wcout << ws.str() << std::endl;
std::wofstream file("C:\\a.txt");
file << p << endl;
return 0;
}
Отладчик показал, что все wss, s и p имеют ожидаемые значения (т.е. «àéêù»), как и выходной файл. Однако то, что появилось в консоли, было óúÛ¨.
Таким образом, проблема заключается в консоли Visual Studio, а не в C ++. Воспользовавшись отличным ответом Бахбара, я добавил:
SetConsoleOutputCP(1252);
в качестве первой строки, после чего вывод консоли появился так, как должен.