2013-07-19 39 views
11

Tôi đang làm việc với ứng dụng cũ và tôi đang cố gắng tìm ra sự khác biệt giữa các ứng dụng được biên dịch với Multi byte character setNot Set theo tùy chọn Character Set.Bộ ký tự Visual Studio 'Không được đặt' vs 'Bộ ký tự nhiều byte'

Tôi hiểu rằng biên soạn với định nghĩa Multi byte character set_MBCS cho phép đa byte trang mã ký tự thiết lập để được sử dụng, và sử dụng Not set không định nghĩa _MBCS, trong trường hợp này chỉ đơn byte trang mã ký tự được cho phép.

Trong trường hợp đó Not Set được sử dụng, tôi giả sử sau đó rằng chúng tôi chỉ có thể sử dụng bộ ký tự trang mã duy nhất byte được tìm thấy trên trang này: http://msdn.microsoft.com/en-gb/goglobal/bb964654.aspx

Vì vậy, tôi thích hợp trong suy nghĩ đó là Not Set là được sử dụng, ứng dụng sẽ không thể mã hóa và viết hoặc đọc các ngôn ngữ phía đông xa vì chúng được định nghĩa trong các trang mã ký tự byte kép (và dĩ nhiên là Unicode)?

Sau đây, nếu tập hợp Multi byte character được xác định, cả hai trang mã bộ ký tự đơn và đa byte có sẵn hay chỉ các trang mã ký tự nhiều byte? Tôi đoán nó phải là cả hai cho các ngôn ngữ châu Âu được hỗ trợ.

Cảm ơn,

Andy

liệu đọc thêm

Những câu trả lời trên các trang này không trả lời câu hỏi của tôi, nhưng giúp trong sự hiểu biết của tôi: About the "Character set" option in visual studio 2010

Nghiên cứu

Vì vậy, cũng giống như nghiên cứu làm việc ...Với locale tôi thiết lập như Nhật

Ảnh hưởng đến chuỗi mã hóa cứng

char *foo = "Jap text: テスト"; 
wchar_t *bar = L"Jap text: テスト"; 

Biên soạn với Unicode

* foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis (Code page 932)
* bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 or UCS-2

Biên soạn với Multi byte character set

* foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis (Code page 932)
* thanh = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 00 20 00 3a c6 30 b9 30 c8 30 == UTF-16 or UCS-2

Biên soạn với Not Set

* foo = 4a 61 70 20 74 65 78 74 3a 20 83 65 83 58 83 67 == Shift-Jis (Code page 932)
* bar = 4a 00 61 00 70 00 20 00 74 00 65 00 78 00 74 00 3a 00 20 00 c6 30 b9 30 c8 30 == UTF-16 or UCS-2

Kết luận: mã hóa ký tự không có bất kỳ ảnh hưởng đến chuỗi mã hóa cứng. Mặc dù việc xác định ký tự như trên dường như sử dụng bảng mã được xác định Locale và wchar_t dường như sử dụng UCS-2 hoặc UTF-16.

Sử dụng chuỗi được mã hóa trong các phiên bản/A W của Win32 API

Vì vậy, sử dụng đoạn mã sau:

char *foo = "C:\\Temp\\テスト\\テa.txt"; 
wchar_t *bar = L"C:\\Temp\\テスト\\テw.txt"; 

CreateFileA(bar, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
CreateFileW(foo, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

Biên soạn với Unicode

Kết quả: Cả hai tập tin được tạo ra

Biên soạn với Multi byte character set

Kết quả: Cả hai tập tin được tạo ra

Biên soạn với Not set

Kết quả: Cả hai tập tin được tạo ra

Kết luận: Cả hai phiên bản AW của API mong đợi mã hóa như nhau bất kể bộ ký tự được chọn. Từ đó, có lẽ chúng ta có thể giả định rằng tất cả tùy chọn Character Set là chuyển đổi giữa phiên bản của API. Vì vậy, phiên bản A luôn mong đợi các chuỗi trong mã hóa của trang mã hiện tại và phiên bản W luôn mong đợi UTF-16 hoặc UCS-2.

file mở bằng W và A Win32 API

Vì vậy, sử dụng đoạn mã sau:

char filea[MAX_PATH] = {0}; 
OPENFILENAMEA ofna = {0}; 
ofna.lStructSize = sizeof (ofna); 
ofna.hwndOwner = NULL ; 
ofna.lpstrFile = filea ; 
ofna.nMaxFile = MAX_PATH; 
ofna.lpstrFilter = "All\0*.*\0Text\0*.TXT\0"; 
ofna.nFilterIndex =1; 
ofna.lpstrFileTitle = NULL ; 
ofna.nMaxFileTitle = 0 ; 
ofna.lpstrInitialDir=NULL ; 
ofna.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ; 

wchar_t filew[MAX_PATH] = {0}; 
OPENFILENAMEW ofnw = {0}; 
ofnw.lStructSize = sizeof (ofnw); 
ofnw.hwndOwner = NULL ; 
ofnw.lpstrFile = filew ; 
ofnw.nMaxFile = MAX_PATH; 
ofnw.lpstrFilter = L"All\0*.*\0Text\0*.TXT\0"; 
ofnw.nFilterIndex =1; 
ofnw.lpstrFileTitle = NULL; 
ofnw.nMaxFileTitle = 0 ; 
ofnw.lpstrInitialDir=NULL ; 
ofnw.Flags = OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST ; 

GetOpenFileNameA(&ofna); 
GetOpenFileNameW(&ofnw); 

và chọn một trong hai:

  • C: \ Temp \ テ ス ト \ テ openw .txt
  • C: \ Temp \ テ ス ト \ テ openw.txt

Sản lượng:

Khi biên soạn với Unicode

* filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 = = Shift-Jis (Code page 932)
* filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 or UCS-2

Khi biên soạn với Multi byte character set

* filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 83 65 5c 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (Code page 932)
* filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 or UCS-2

Khi được biên dịch với Not Set

* filea = 43 3a 5c 54 65 6d 70 5c 83 65 83 58 83 67 5c 83 65 6f 70 65 6e 61 2e 74 78 74 == Shift-Jis (Code page 932)
* filew = 43 00 3a 00 5c 00 54 00 65 00 6d 00 70 00 5c 00 c6 30 b9 30 c8 30 5c 00 c6 30 6f 00 70 00 65 00 6e 00 77 00 2e 00 74 00 78 00 74 00 == UTF-16 or UCS-2

Kết luận: Again , cài đặt Character Set không có ảnh hưởng đến hoạt động của API Win32. Phiên bản A dường như luôn trả về một chuỗi có mã hóa của trang mã đang hoạt động và mã W luôn trả về UTF-16 hoặc UCS-2. Tôi thực sự có thể thấy điều này được giải thích một chút trong câu trả lời tuyệt vời này: https://stackoverflow.com/a/3299860/187100.

Cuối cùng Conculsion

Hans dường như là đúng khi ông nói rằng các định nghĩa không thực sự có bất kỳ ma thuật để nó, ngoài việc thay đổi API Win32 để sử dụng hoặc W hoặc A. Do đó, tôi thực sự không thể thấy bất kỳ sự khác biệt nào giữa Not SetMulti byte character set.

Trả lời

6

Không, đó không thực sự là cách hoạt động của nó. Điều duy nhất xảy ra là macro được định nghĩa, nó không có hiệu ứng ma thuật trên trình biên dịch. Đó là rất hiếm khi thực sự viết mã sử dụng #ifdef _MBCS để kiểm tra macro này.

Bạn hầu như luôn luôn duy trì chức năng trợ giúp để thực hiện chuyển đổi. Giống như WideCharToMultiByte(), OLE2A() hoặc wctombs(). Đó là các hàm chuyển đổi luôn xem xét mã hóa nhiều byte, như được hướng dẫn bởi trang mã. _MBCS là một tai nạn lịch sử, có liên quan chỉ 25+ năm trước khi mã hóa nhiều byte không phổ biến. Giống như việc sử dụng mã hóa không phải Unicode cũng là một tạo tác lịch sử trong những ngày này.

+0

Vì vậy, nếu tôi hiểu chính xác, nếu tôi xác định một chuỗi mã hóa cứng, nói char * foo = "テ ス ト". Chuỗi được trỏ đến bởi foo không được xác định bởi cài đặt bộ ký tự như thế nào? Có lẽ mã hóa của tập tin mã có chứa dòng đó? (Tôi đang cố gắng kiểm tra các lý thuyết này vào lúc này) – Andy

+0

Điều đó sẽ buộc trình soạn thảo văn bản của bạn chọn mã hóa thích hợp cho tệp mã nguồn. Bản thân nó là một nguồn tai nạn. Nếu nó chọn một mã hóa Unicode, utf-8 là phổ biến, bạn có trách nhiệm để có được trình biên dịch của bạn để có được sulky về nó. C4566 trên máy của tôi.Chỉ có bao giờ xem xét viết nó như thế này nếu bạn sống ở Nhật Bản và không xem xét di chuyển bất cứ lúc nào sớm. –

+0

Ok, vậy có vẻ như giờ tôi đã hiểu rõ hơn một chút. Các định nghĩa không thực sự làm nhiều, trang mã được đặt trên máy bất kể cách ứng dụng được biên dịch, và định nghĩa chỉ thay đổi API Win32 và dựa trên việc đó là W hay A, tôi đoán nó sẽ trả về mã trang (công cụ được mã hoá nhiều byte hoặc một byte) (A) hoặc UTF-16 (W)? – Andy

0

Trong reference nó được tuyên bố rằng:

Theo định nghĩa, các bộ ký tự ASCII là một tập hợp con của tất cả bộ multibyte ký tự. Trong nhiều bộ ký tự nhiều byte, mỗi ký tự trong phạm vi 0x00 - 0x7F giống với ký tự mà có cùng giá trị trong bộ ký tự ASCII. Ví dụ: trong cả hai chuỗi ký tự ASC2 và MBCS, một ký tự NULL 1 byte ('\ 0') có giá trị 0x00 và chỉ ra ký tự null kết thúc.

Khi bạn đoán, bằng cách bật _MBCS Visual Studio cũng hỗ trợ ASCII bộ ký tự đơn.

Trong một giây reference, đơn bộ ký tự dường như được hỗ trợ ngay cả khi chúng tôi cho phép _MBCS:

MBCS/Unicode di động: Sử dụng tập tin tiêu đề Tchar.h, bạn có thể xây dựng byte đơn , MBCS và các ứng dụng Unicode từ cùng một nguồn. Tchar.h định nghĩa các macro có tiền tố _tcs, ánh xạ tới các hàm str, _mbs hoặc wcs, nếu thích hợp. Để xây dựng MBCS, hãy xác định ký hiệu _MBCS. Để xây dựng Unicode, hãy xác định biểu tượng _UNICODE. Theo mặc định, _MBCS là được xác định cho các ứng dụng MFC. Để biết thêm thông tin, hãy xem Generic-Text Ánh xạ trong Tchar.h.

+0

Nhưng bằng cách không sử dụng '_MBCS' không phải là API sử dụng trang mã ký tự byte đơn dựa trên ngôn ngữ, chẳng hạn như được xác định tại: http://msdn.microsoft.com/en-gb/goglobal/ bb964654.aspx? Vì vậy, mỗi trong số tất cả đều bắt đầu với phạm vi ASCII, nhưng chúng tiếp tục xác định các ký tự nước ngoài khác nữa. – Andy

+0

@Andy, Có, ASCII là bộ ký tự 7 bit có 128 ký tự trong khi mã hóa miền địa phương đơn (8 bit) có thể mã hóa 256 ký tự. –

+0

yup, vì vậy các câu hỏi vẫn còn, nếu MBCS được xác định, là các trang mã ký tự byte đơn bị loại trừ (và do đó nói các ký tự tiếng Thái)? Và nếu tôi biên dịch mà không có MBSC, tôi đoán ứng dụng sẽ không thể xử lý các ký tự phía đông xa vì nó bị giới hạn ở các trang mã ký tự byte đơn> – Andy

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