2011-09-21 31 views
7

Tôi đang cố gắng in ra một chuỗi wchar_t *. Mã đi dưới đây:char vs wchar_t

#include <stdio.h> 
#include <string.h> 
#include <wchar.h> 

char *ascii_ = "中日友好"; //line-1 
wchar_t *wchar_ = L"中日友好"; //line-2 

int main() 
{ 
    printf("ascii_: %s\n", ascii_); //line-3 
    wprintf(L"wchar_: %s\n", wchar_); //line-4 
    return 0; 
} 

//Output 
ascii_: 中日友好 

Câu hỏi:

  1. Rõ ràng tôi không nên gán CJK để char * con trỏ ở dòng 1, nhưng tôi chỉ làm điều đó, và đầu ra của dòng -3 là đúng, vậy tại sao? Làm thế nào có thể printf() trong dòng-3 cho tôi những ký tự không phải ascii? Liệu nó biết mã hóa bằng cách nào đó?

  2. Tôi giả sử mã ở dòng 2 và dòng 4 là chính xác, nhưng tại sao tôi không nhận được bất kỳ đầu ra nào của dòng 4?

+0

Bạn đang sử dụng trình biên dịch nào? GCC mặc định là Utf-8 o hầu hết các nền tảng. Có vẻ như một vấn đề mã hóa với tôi. – cyco130

+0

@ cyco130, vâng, gcc – Alcott

Trả lời

8

Trước hết, bạn không nên sử dụng các ký tự không phải ascii trong mã nguồn. Những gì có thể xảy ra là các ký tự Trung Quốc đang được mã hóa như UTF-8 mà làm việc với ascii.

Hiện tại, tại sao wprintf() không hoạt động. Điều này phải làm với định hướng luồng. Mỗi luồng chỉ có thể được đặt thành bình thường hoặc rộng. Sau khi thiết lập, nó không thể thay đổi. Nó được thiết lập lần đầu tiên nó được sử dụng. (là ascii do printf). Sau đó, wprintf sẽ không hoạt động do định hướng không chính xác.

Nói cách khác, khi bạn sử dụng printf() bạn cần tiếp tục sử dụng printf(). Tương tự, nếu bạn bắt đầu với wprintf(), bạn cần tiếp tục sử dụng wprintf().

Bạn không thể xen giữa printf()wprintf(). (Ngoại trừ trên Windows)

EDIT:

Để trả lời câu hỏi về việc tại sao dòng wprintf không hoạt động thậm chí của chính nó. Có thể là do mã được biên dịch sao cho định dạng UTF-8 của 中日友好 được lưu trữ thành wchar_. Tuy nhiên, wchar_t cần mã hóa unicode 4 byte. (2-byte trong Windows)

Vì vậy, có hai lựa chọn mà tôi có thể nghĩ đến:

  1. Đừng bận tâm với wchar_t, và chỉ gắn bó với đa byte char s. Đây là cách dễ dàng, nhưng có thể phá vỡ nếu hệ thống của người dùng không được đặt thành ngôn ngữ Trung Quốc.
  2. Sử dụng wchar_t, nhưng bạn sẽ cần phải mã hóa các ký tự Trung Quốc bằng cách sử dụng chuỗi thoát unicode. Điều này rõ ràng sẽ làm cho nó không thể đọc được trong mã nguồn, nhưng nó sẽ làm việc trên bất kỳ máy nào có thể in phông chữ ký tự Trung Quốc bất kể ngôn ngữ.
+0

nếu sử dụng unicode escape seq, tôi phải tìm ra mỗi từ của seq, phải không? Điều đó sẽ có khá nhiều việc phải làm,: P – Alcott

+1

Đúng. Tuy nhiên, tôi chắc chắn điều này là đủ phổ biến, nơi bạn có thể tìm thấy một công cụ trực tuyến mà bạn chỉ có thể sao chép và dán văn bản Trung Quốc và nó sẽ cung cấp cho bạn chuỗi thoát unicode. Và để giữ cho mã có thể đọc được, bạn có thể giữ văn bản Trung Quốc thực tế bên cạnh chuỗi thoát là một nhận xét. – Mysticial

+0

cảm ơn Mysticial – Alcott

6

Dòng 1 không phải là ascii, đó là bất kỳ mã hóa đa byte nào được trình biên dịch của bạn sử dụng lúc biên dịch. Trên các hệ thống hiện đại có thể là UTF-8. printf không biết mã hóa. Nó chỉ gửi byte để stdout, và miễn là mã hóa phù hợp, mọi thứ đều ổn.

Một vấn đề bạn cần lưu ý là các dòng 3 và 4 cùng nhau gọi hành vi không xác định. Bạn không thể kết hợp io dựa trên ký tự và ký tự rộng trên cùng một số FILE (stdout).Sau khi hoạt động đầu tiên, FILE có một "hướng" (hoặc là byte hoặc rộng), và sau đó bất kỳ nỗ lực nào để thực hiện các hoạt động của các kết quả định hướng đối diện trong UB.

+0

Tôi nhận xét printf() dòng, tôi có một số đầu ra nhưng không phải là ký tự Trung Quốc. Tại sao? – Alcott

+0

Có thể mã hóa của miền địa phương là sai. –

+0

mã hóa của miền địa phương? Làm thế nào để sửa chữa nó? – Alcott

1

Bạn đang bỏ qua một bước và do đó nghĩ nhầm.

Bạn có tệp C trên đĩa, chứa byte. Bạn có một chuỗi "ASCII" và một chuỗi rộng.

Chuỗi ASCII lấy các byte giống hệt như trong dòng 1 và xuất chúng. Điều này hoạt động miễn là mã hóa phía bên của người dùng giống với bên phía lập trình viên.

Chuỗi rộng đầu tiên giải mã các byte đã cho thành các điểm mã unicode và được lưu trữ trong chương trình - có thể điều này sai về phía bạn. Ngày đầu ra chúng được mã hóa một lần nữa theo mã hóa ở phía người dùng. Điều này đảm bảo rằng các ký tự này được phát ra như chúng được dự định, không phải khi chúng được nhập vào.

Trình biên dịch của bạn giả định mã hóa sai hoặc thiết bị đầu cuối đầu ra của bạn được thiết lập sai.

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