Próbuję odczytać plik tekstowy zakodowany w Shift-JIS (cp 932) przy użyciu std :: wifstream i std :: getline. Poniższy kod działa w VS2010, ale nie w VS2013:Dekodowanie Shift-JIS nie działa przy użyciu wifstrem w 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();
Plik zawiera kilka linii, gdzie pierwsza linia zawiera tylko znaki ASCII, a drugi to japoński scenariusz. Tak więc, po uruchomieniu tego fragmentu, line1
powinien zawierać wiersz ASCII, line2
skrypt japoński, a good
powinien być prawdziwy.
Po kompilacji w VS2010 wynik jest zgodny z oczekiwaniami. Ale po kompilacji w VS2013, line1
zawiera linię ASCII, ale line2
jest pusta, a good
jest fałszywa.
Po debugowaniu do CRT (jako źródło dostarczono Visual Studio) i odkryłem, że wewnętrzna funkcja o nazwie _Mbrtowc
(w pliku xmbtowc.c) została zmodyfikowana między dwiema wersjami i sposób, w jaki używają do wykrywania zmieniono bajt wiodący znaku dwubajtowego, a ten w VS 2013 nie wykrył bajtu wiodącego, a zatem nie dekoduje strumienia bajtów.
Dalsze debugowania wykazała punktu, w którym _Isleadbyte
tablicy A _Cvtvec
obiektu jest inicjowany (w funkcji _Getcvt()
w pliku xwctomb.c) oraz że inicjalizacja wytwarza błędny wynik. Wydaje się, że zawsze używa strony kodowej 1252, która jest domyślną stroną kodową w moim systemie, a nie 932, która jest ustawiona dla używanego strumienia. Jednak nie mogłem zdecydować, czy jest to zgodne z projektem, i brakowało mi pewnych wymaganych kroków, aby uzyskać dobry wynik, lub jest to rzeczywiście błąd w CRT dla VS2013.
Niestety nie mam zainstalowanego VS2012, więc nie mogłem przetestować tej wersji.
Wszelkie spostrzeżenia na ten temat są mile widziane!
post to connect.microsoft.com –
Chciałbym zacząć od próby 'nasycić()' nowego lokum przed otwarciem pliku: Myślę, że strumień może odczytać znaki podczas gdy otwarta i znaki są czytane nie zmieni on używanego aspektu 'std :: codecvt <...>'. –
@ DietmarKühl Właśnie sprawdziłem, ale wyniki były takie same: działa w VS2010, ale nie działa tak samo w VS2013. –