Не могу прочитать юникод (японский) из файла - PullRequest
2 голосов
/ 10 февраля 2011

Привет! У меня есть файл, содержащий текст на японском языке, сохраненный как файл Unicode.

Мне нужно прочитать файл и вывести информацию на стандартный вывод.

Я использую Visual Studio2008

int main()   
{  
      wstring line;  
      wifstream myfile("D:\sample.txt"); //file containing japanese characters, saved as unicode file  
      //myfile.imbue(locale("Japanese_Japan"));  
      if(!myfile)  
            cout<<"While opening a file an error is encountered"<<endl;  
      else  
            cout << "File is successfully opened" << endl;  
      //wcout.imbue (locale("Japanese_Japan"));  
      while ( myfile.good() )  
      {  
            getline(myfile,line);  
            wcout << line << endl;  
      }  
      myfile.close();  
      system("PAUSE");  
      return 0;  
}  

Эта программа генерирует случайный вывод, и я не вижу японского текста на экране.

Ответы [ 4 ]

5 голосов
/ 10 февраля 2011

О, мальчик.Добро пожаловать в мир забавных, забавных кодировок символов.

Первое, что вам нужно знать, это то, что ваша консоль не является Unicode в Windows.Единственный способ увидеть японские символы в консольном приложении - это, если вы установите для своего языка не-Unicode (ANSI) японский.Это также сделает обратные слэши похожими на символы иены и пути разрыва, содержащие символы с европейским акцентированием, для программ, использующих API-интерфейс ANSI Windows (который был предполагается устаревшим, когда появилась Windows XP, но люди все еще используют по сей день...)

Итак, первое, что вы захотите сделать - это создать программу с графическим интерфейсом.Но я оставлю это как упражнение заинтересованному читателю.

Во-вторых, существует много способов представления текста.Сначала вам нужно выяснить используемую кодировку.Это UTF-8?UTF-16 (и если да, маленький или большой порядковый номер?) Shift-JIS?EUC-JP?Вы можете использовать wstream только для непосредственного чтения, если файл имеет младший порядок UTF-16.И даже тогда вам нужно futz со своим внутренним буфером .Что-нибудь кроме UTF-16, и вы получите нечитаемый мусор.И это только на Windows!Другие ОС могут иметь другое представление wstream.Лучше вообще не использовать wstream s.

Итак, давайте предположим, что это , а не UTF-16 (для полной общности).В этом случае вы должны прочитать его как поток символов - , а не , используя wstream.Затем вы должны преобразовать эту строку символов в UTF-16 (при условии, что вы используете Windows! Другие ОС, как правило, используют UTF-8 char* s).На окнах это можно сделать с помощью MultiByteToWideChar.Убедитесь, что вы ввели правильное значение кодовой страницы, а CP_ACP или CP_OEMCP почти всегда являются неправильным ответом.

Теперь вам может быть интересно, как определить, какая кодовая страница (т. Е. Кодировка символов)верно.Короткий ответ: Вы не .Нет никакого prima facie способа посмотреть на текстовую строку и сказать, какая это кодировка.Конечно, могут быть подсказки - например, если вы видите метку порядка следования байтов , скорее всего, это какой-то вариант Юникода, который делает эту метку.Но в целом пользователь должен сказать вам, или попытаться угадать, полагаясь на то, что пользователь исправит вас, если вы ошибаетесь, или вы должны выбрать фиксированный набор символов и не пытаться поддерживать какие-либодр.

0 голосов
/ 10 февраля 2011

Две ошибки:

std::wifstream(L"D:\\sample.txt");

И не смешивайте cout и wcout.

Также убедитесь, что ваш файл закодирован в формате UTF-16, Little-Endian. Если это не так, у вас будут проблемы с чтением.

0 голосов
/ 10 февраля 2011

wfstream использует wfilebuf для фактического чтения и записи данных.По умолчанию wfilebuf использует внутренний буфер символов, что означает, что текст в файле считается узким и преобразуется в широкий, прежде чем вы его увидите.Поскольку текст был действительно широким, вы получаете беспорядок.

Решение состоит в том, чтобы заменить буфер wfilebuf на широкий.

Возможно, вам также нужно открыть файл в двоичном виде.

const size_t bufsize = 128;
wchar_t buffer[bufsize];
wifstream myfile("D:\sample.txt", ios::binary);
myfile.rdbuf()->pubsetbuf(buffer, 128);

Убедитесь, что объект потока переживает буфер!

Подробности см. Здесь: http://msdn.microsoft.com/en-us/library/tzf8k3z8(v=VS.80).aspx

0 голосов
/ 10 февраля 2011

Кто-то здесь имел ту же проблему с русскими символами (он использует basic_ifstream , который должен быть таким же, как wifstream согласно этой странице ). В комментариях к этому вопросу они также ссылаются на этот , который должен помочь вам в дальнейшем.

Если все правильно поняли, кажется, что wifstream правильно читает символы, но ваша программа пытается преобразовать их в любой язык, в котором работает ваша программа.

...