2016-12-24 15 views
6

Nhược bằng tôi lấy chiều dài của một chuỗi có chứa một nhân vật bên ngoài bảng ASCII 7-bit, tôi nhận được kết quả khác nhau trên Windows và Linux:C Chuỗi mã hóa Windows/Linux

Windows: strlen("ö") = 1 
Linux: strlen("ö") = 2 

Trên một máy tính Windows chuỗi rõ ràng được mã hóa ở định dạng ascii "mở rộng" là 0xF6, trong khi trên một máy Linux, nó được mã hóa bằng UTF-8 với 0xC3 0x96, cung cấp độ dài 2 ký tự.

Câu hỏi:

Tại sao chuỗi C được mã hóa khác trên máy tính Windows và Linux?


Câu hỏi đặt ra đã đưa ra trong một cuộc thảo luận tôi đã có với một thành viên diễn đàn đồng trên Mã Review (see this thread).

+0

Cả hai tệp nguồn có sử dụng cùng một cài đặt mã hóa và BOM không? – sidyll

+1

Có vẻ như mã hóa có thể được chọn từ cài đặt cục bộ. Và có vẻ như bạn cũng có thể đặt nó? https://gcc.gnu.org/onlinedocs/cpp/Invocation.html (-fwide-exec-charset = charset) – Sush

+0

Vì trong Windows CP-1252 là mặc định, và có một số vấn đề với UTF-8 khi Microsoft muốn giữ tương thích ngược. Xem cái này trên SU [Windows 7 UTF-8 và Unicode] (// superuser.com/q/221593) – Danh

Trả lời

5

Tại sao chuỗi C được mã hóa khác trên máy tính Windows và Linux?

Thứ nhất, đây không phải là Windows/Linux (Hệ điều hành) phát hành, nhưng một trình biên dịch một trình biên dịch như tồn tại trên Windows mà mã hóa như gcc (phổ biến trên Linux).

này được cho phép bởi C và hai nhà sản xuất trình biên dịch đã ghi danh xếp hạng triển khai khác nhau cho mỗi mục tiêu lập trình riêng của họ, MS sử dụng CP-1252 và Linux sử dụng Unicode. @Danh. Lựa chọn trước Unicode của MS. Không ngạc nhiên khi các nhà sản xuất trình biên dịch khác nhau sử dụng các giải pháp khác nhau.

5.2.1 Character đặt
1 Hai bộ ký tự và chuỗi collating liên quan của họ sẽ de fi ned: tập trong đó nguồn fi les được viết (nhân vật nguồn thiết), và các thiết lập giải thích trong môi trường thực thi (ký tự thực thi). Mỗi bộ được chia thành bộ ký tự cơ bản, có nội dung được cung cấp bởi điều này và tập hợp không hoặc nhiều thành viên miền địa phương (không phải là thành viên của bộ ký tự cơ bản) được gọi là ký tự mở rộng . Tập hợp kết hợp còn được gọi là bộ ký tự mở rộng. Giá trị của các thành viên của bộ ký tự thực thi là được triển khai. C11dr §5.2.1 1 (nhấn mạnh của tôi)

strlen("ö") = 1 
strlen("ö") = 2 

"ö" được mã hóa mỗi ký tự nguồn của trình biên dịch mở rộng ký tự.

Tôi nghi ngờ MS tập trung vào việc duy trì cơ sở mã của họ và khuyến khích các ngôn ngữ khác. Linux chỉ đơn giản là một bộ chuyển đổi Unicode trước đó thành C, mặc dù MS đã là một bộ ảnh hưởng đầu tiên của Unicode.

Unicode support grows, tôi hy vọng đó sẽ là giải pháp của tương lai.

+0

C và UTF-8, cơn ác mộng. Hy vọng rằng C sẽ thêm hỗ trợ UTF-8 trong tương lai. Nếu C muốn tiếp tục sống, anh ta phải thay đổi. http://julialang.org/utf8proc không dễ sử dụng. – Stargateur

+1

@Stargateur Đồng ý về đêm. Vấn đề không phải là quá nhiều của C áp dụng hỗ trợ UTF-8 - đó là tương đối dễ dàng - nó tồn tại kể từ C11. (Xem _6.4.5 Chuỗi literals_ như 'u8" Hellö "'), nhưng duy trì/giảm giá trước khi các ký tự mở rộng tiếp cận song song đang rơi xuống bên đường. Sau khi tất cả C, vẫn có digraphs/trigraphs: một giải pháp di sản cho các vấn đề liên quan đến ngôn ngữ. Nó sẽ mất nhiều thập kỷ. – chux

+0

Cảm ơn bạn đã trả lời! Tôi đang sử dụng gcc trên cả hai hệ thống phiên bản 4.8.1 trên các cửa sổ và 4.8.4 trên Linux với các tùy chọn tương tự (-O0 -g3 -Wall -c -fmessage-length = 0). Tôi sẽ chơi một chút với các tùy chọn như đề xuất của Sush. –