2014-10-28 20 views
5

Tôi đang cố gắng đọc tệp văn bản được mã hóa trong Shift-JIS (cp 932) sử dụng std :: wifstream và std :: getline. Mã sau hoạt động trong VS2010 nhưng không thành công trong VS2013:Giải mã Shift-JIS không thành công bằng cách sử dụng wifstrem trong Visual C++ 2013

std::wifstream in; 
in.open("data932.txt"); 

const std::locale locale(".932"); 

in.imbue(locale); 

std::wstring line1, line2; 
std::getline(in, line1); 
std::getline(in, line2); 
const bool good = in.good(); 

Tệp có chứa một số dòng, dòng đầu tiên chỉ chứa ký tự ASCII và chữ thứ hai là tập lệnh tiếng Nhật. Do đó, khi đoạn mã này chạy, line1 phải chứa dòng ASCII, line2 tập lệnh tiếng Nhật và good phải đúng.

Khi được biên dịch trong VS2010, kết quả như mong đợi. Nhưng khi được biên soạn trong VS2013, line1 chứa dòng ASCII, nhưng line2 trống và good là sai.

Tôi đã gỡ rối vào CRT, (như nguồn được cung cấp với Visual Studio) và thấy rằng một hàm bên trong có tên là _Mbrtowc (trong tệp xmbtowc.c) đã được sửa đổi giữa hai phiên bản và cách chúng sử dụng để phát hiện một byte dẫn của một ký tự byte kép đã được thay đổi, và một trong VS 2013 không phát hiện được một byte dẫn, do đó không giải mã được luồng byte.

Gỡ lỗi thêm cho thấy một điểm, trong đó một mảng _Cvtvec của đối tượng _Isleadbyte được khởi tạo (trong hàm _Getcvt(), trong tệp xwctomb.c) và khởi tạo đó tạo ra kết quả sai. Có vẻ như nó luôn luôn sử dụng mã trang 1252, đó là trang mã mặc định trên hệ thống của tôi, và không phải 932 được thiết lập cho luồng đang sử dụng. Tuy nhiên, tôi không thể quyết định nếu nó là do thiết kế, và tôi đã bỏ lỡ một số bước cần thiết để có được một kết quả tốt, hoặc điều này thực sự là một lỗi trong CRT cho VS2013.

Rất tiếc, tôi chưa cài đặt VS2012 nên tôi không thể thử nghiệm trên phiên bản đó.

Mọi thông tin chi tiết về chủ đề này đều được hoan nghênh!

+0

bài viết này để connect.microsoft.com –

+0

tôi sẽ bắt đầu cố gắng để 'thấm nhuần() 'ngôn ngữ mới trước khi mở file: Tôi nghĩ rằng dòng có thể đọc các ký tự trong mở và một khi nhân vật được đọc nó sẽ không thay đổi 'std :: codecvt <...>' được sử dụng. –

+0

@ DietmarKühl Tôi vừa kiểm tra nó, nhưng kết quả là như nhau: hoạt động trong VS2010, nhưng không thành công theo cách tương tự trong VS2013. –

Trả lời

2

Tôi đã tìm thấy giải pháp thay thế: nếu để tạo miền địa phương, tôi thay đổi rõ ràng trang mã MBC toàn cục, ngôn ngữ được khởi tạo chính xác và các dòng được đọc và giải mã như mong đợi.

const int oldMbcp = _getmbcp(); 
_setmbcp(932); 
const std::locale locale("Japanese_Japan.932"); 
_setmbcp(oldMbcp); 
+0

Nhưng như thế này dường như chỉ là một cách giải quyết, tôi sẽ không chấp nhận nó như một câu trả lời ... –

+0

Tôi đã [nhấn] (http://stackoverflow.com/questions/33254089/double-byte-character-sequence-conversion-issue -in-visual-studio-2015) bởi điều này là tốt. Tôi đã điền vào [báo cáo lỗi] (https://connect.microsoft.com/VisualStudio/feedback/details/1925650) về vấn đề này. – wilx

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