2010-06-28 7 views
6

Мой код в основном это:C++: символы, выводимые неверно?

wstring japan = L"日本"; 
wstring message = L"Welcome! Japan is "; 

message += japan; 

wprintf(message.c_str()); 

Я желающая использовать широкие строки, но я не знаю, как они выводятся, поэтому я использовал wprintf. Когда я бегу что-то такое, как:

./widestr | hexdump 

В шестнадцатеричные кодовые создать это:

65 57 63 6c 6d 6f 21 65 4a 20 70 61 6e 61 69 20 20 73 3f 3f 
e W c l m o ! e J  p a n a i  s ? ? 

Почему все они прыгнули в порядке? Я имею в виду, если wprintf ошибается, я все равно не понимаю, почему он выдавал бы в таком определенном беспорядочном порядке!

Редактировать: endianness или еще что-то? они, похоже, вращают каждый два символа. да.

EDIT 2: Я попытался использовать wcout, но он выводит точно такие же шестнадцатеричные кодовые точки. Weird!

+0

Возможно, вам стоит попробовать 'cout << message << endl'. – phimuemue

+0

@phimuemue, он не работает, он отправляет мне примерно 30 ошибок, сначала «widestr.cpp: 18: ошибка: нет соответствия для« operator << »в 'std :: cout << message'', включая многие из них ostream черт характера или что-то в этом роде, он не будет выводить широкую строку! –

+1

Какую платформу и компилятор вы используете? – hlovdal

ответ

11

Вам нужно определить локали

#include <stdio.h> 
    #include <string> 
    #include <locale> 
    #include <iostream> 

    using namespace std; 

    int main() 
    { 

      std::locale::global(std::locale("")); 
      wstring japan = L"日本"; 
      wstring message = L"Welcome! Japan is "; 

      message += japan; 

      wprintf(message.c_str()); 
      wcout << message << endl; 
    } 

Работы, как и ожидалось (то есть преобразовать строку широких сужать UTF-8 и печатать его).

При определении глобального языкового стандарта «» - установить язык системы (если это UTF-8 это будет быть распечатано, как UTF-8 - т.е. wstring будет преобразован)

Edit: забыть, что я сказал о sync_with_stdio - это неверно, они синхронизируются по умолчанию. Не нужно.

+1

Вы делаете это звучащим как 'sync_with_stdio' и' wcout' - альтернативы; они делают совершенно разные вещи. 'sync_with_stdio' требуется, если вы хотите чередовать функции потока C (например,' wprintf') с использованием потока C++ ('wcout'); 'imbue' необходимо, если вы хотите изменить локаль, используемую' wcout'. –

+0

Я не могу его протестировать, но 'wcout' должен работать без настроек кодовой страницы в Windows, потому что' wchar_t' является кодовым UTF-16 в Windows и UTF-16 является только собственной кодировкой Windows. Поэтому 'std :: wcout' должен использовать' WriteConsoleW' без какого-либо преобразования локали. Если это не так, это ошибка библиотеки. – Philipp

+2

@Philipp Это не так, как это определено стандартом. Стандарт говорит, что широкие символы должны быть преобразованы в узкую кодировку в соответствии с кодовой страницей локали. И это то, что сделано. Проблема с Windows заключается в том, что она не поддерживает UTF-8. Поэтому для Windows вам, вероятно, нужно использовать 'locale :: globale (locale (« Япония »)), и в нем будет использоваться кодировка Shift-JIS. В противном случае он не сможет преобразовать символы. – Artyom

 Смежные вопросы

  • Нет связанных вопросов^_^