2010-06-28 27 views
6

Mã của tôi là về cơ bản này:C++: ký tự rộng xuất hiện không chính xác?

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

message += japan; 

wprintf(message.c_str()); 

Tôi đang có nhu cầu sử dụng chuỗi rộng nhưng tôi không biết làm thế nào họ đang outputted, vì vậy tôi sử dụng wprintf. Khi tôi chạy một cái gì đó như:

./widestr | hexdump 

Các codepoints hexidecimal tạo này:

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 ? ? 

Tại sao tất cả họ đều nhảy theo thứ tự? Tôi có nghĩa là nếu wprintf là sai tôi vẫn không nhận được lý do tại sao nó sẽ đầu ra trong một thứ tự xáo trộn cụ thể như vậy!

chỉnh sửa: endianness hoặc gì đó? họ dường như xoay mỗi hai nhân vật. Huh.

CHỈNH SỬA 2: Tôi đã thử sử dụng wcout, nhưng kết quả đầu ra chính xác cùng một điểm thập lục phân. Kỳ dị!

+0

Có thể bạn nên thử 'cout << message << endl'. – phimuemue

+0

@phimuemue, Nó không hoạt động, nó gửi cho tôi khoảng 30 lỗi, đầu tiên là 'widestr.cpp: 18: lỗi: không khớp cho 'toán tử <<' trong 'std :: cout << message'', bao gồm nhiều đặc điểm ostream char hoặc một cái gì đó, Nó sẽ không sản xuất chuỗi rộng! –

+1

Bạn đang sử dụng nền tảng và trình biên dịch nào? – hlovdal

Trả lời

11

Bạn cần phải xác định locale

#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; 
    } 

trình như mong đợi (ví dụ chuyển đổi chuỗi rộng để thu hẹp UTF-8 và in nó).

Khi bạn xác định miền địa phương toàn cầu "" - bạn thiết lập hệ thống locale (và nếu nó là UTF-8 nó sẽ được in ra dưới dạng UTF-8 - tức là wstring sẽ được chuyển đổi)

Edit: quên những gì tôi đã nói về sync_with_stdio - điều này là không chính xác, chúng được đồng bộ hóa theo mặc định. Không cần thiết.

+1

Bạn tạo âm thanh như 'sync_with_stdio' và' wcout' là các lựa chọn thay thế; họ làm những việc hoàn toàn khác nhau. 'sync_with_stdio' là bắt buộc nếu bạn muốn xen kẽ các hàm dòng C (như' wprintf') với việc sử dụng luồng C++ ('wcout'); 'imbue' là cần thiết nếu bạn muốn thay đổi ngôn ngữ được sử dụng bởi' wcout'. –

+0

Tôi không thể kiểm tra nó, nhưng 'wcout' sẽ hoạt động mà không cần cài đặt mã trên Windows vì' wchar_t' là đơn vị mã UTF-16 trên Windows và UTF-16 là mã hóa duy nhất của Windows. Vì vậy, 'std :: wcout' nên sử dụng' WriteConsoleW' mà không cần bất kỳ chuyển đổi miền địa phương nào. Nếu không, đó là một lỗi thư viện. – Philipp

+2

@Philipp Nó không phải là cách này được xác định theo tiêu chuẩn. Tiêu chuẩn nói rằng các ký tự rộng nên được chuyển đổi thành mã hóa hẹp theo mã của miền địa phương. Và đây là những gì được thực hiện. Vấn đề với Windows là nó không hỗ trợ UTF-8. Vì vậy, đối với Windows, bạn có thể cần phải sử dụng 'locale :: globale (locale (" Japan "))' và nó sẽ sử dụng mã hóa Shift-JIS trong đầu ra. Nếu không, nó sẽ không chuyển đổi các ký tự. – Artyom

Các vấn đề liên quan