C++ Can';t从文件中读取unicode(日语)

C++ Can';t从文件中读取unicode(日语),c++,internationalization,character-encoding,cjk,C++,Internationalization,Character Encoding,Cjk,嗨,我有一个包含日语文本的文件,保存为unicode文件 我需要读取文件并将信息显示到标准输出 我正在使用VisualStudio2008 int main() { wstring line; wifstream myfile("D:\sample.txt"); //file containing japanese characters, saved as unicode file //myfile.imbue(locale("Japanes

嗨,我有一个包含日语文本的文件,保存为unicode文件

我需要读取文件并将信息显示到标准输出

我正在使用VisualStudio2008

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;  
}  
intmain()
{  
环行线;
wifstream myfile(“D:\sample.txt”);//包含日语字符的文件,另存为unicode文件
//imbue(locale(“Japanese_Japan”);
如果(!myfile)
cout有人对俄文字符也有同样的问题(他使用的是basic_ifstream wich,应该与wifstream相同)。在对该问题的评论中,他们还链接到了可以进一步帮助您的内容

如果理解正确,wifstream似乎可以正确读取字符,但您的程序会尝试将它们转换为您的程序正在运行的任何语言环境。

两个错误:

std::wifstream(L"D:\\sample.txt");
不要把
cout
wcout
混在一起


另外,请检查您的文件是否以UTF-16 Little-Endian编码。如果不是这样,您将在读取时遇到问题。

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);
确保缓冲区比流对象更有效


请参阅此处的详细信息:

哦,孩子。欢迎来到角色编码的有趣世界

您需要知道的第一件事是,您的控制台在windows上不是unicode。您在控制台应用程序中看到日文字符的唯一方法是使用日文。这也会使反斜杠看起来像日元符号,并打断使用ANSI windows API的程序中包含欧洲重音字符的路径(当Windows XP出现时,它本应被弃用,但人们至今仍在使用…)

因此,您要做的第一件事是构建一个GUI程序,但我将把它作为练习留给感兴趣的读者

第二,有很多方法来表示文本。你首先需要弄清楚正在使用的编码。UTF-8是UTF-16吗(如果是的话,是小端还是大端?)Shift JIS?EUC-JP?如果文件是小尾端UTF-16格式,您只能使用
wstream
直接读取。即使这样,您也需要。UTF-16以外的任何格式都会导致无法读取的垃圾。这也是Windows上的唯一情况!其他操作系统可能有不同的
wstream
表示形式。最好不要使用
>wstream
s确实如此

因此,我们假设它不是UTF-16(为了充分的通用性)。在这种情况下,您必须将其作为字符流读取-而不是使用
wstream
。然后必须将此字符串转换为UTF-16(假设您使用的是windows!其他操作系统倾向于使用UTF-8
char*
s)。在windows上可以使用。请确保输入正确的代码页值,
CP\u ACP
CP\u OEMCP
几乎总是错误的答案


现在,您可能想知道如何确定哪个代码页(即,字符编码)是正确的。简而言之,答案是你没有。没有一种表面上看文本字符串并说出它是哪种编码的方法。当然,可能会有一些提示——例如,如果你看到一个,很可能是unicode的任何变体打上了这个标记。但一般来说,用户必须告诉你,或者尝试猜测,依靠用户来更正如果你错了,或者你必须选择一个固定的字符集,不要尝试支持任何其他字符集。实际上,wfstream已经在wchar上使用了一个专用的基本文件BUF,事实上,如果不是这样的话,
pubsetbuf
将失败。因此,这段代码只是将缓冲区缩小到128个字符。@bdonlan wfstream使用wfilebuf,它是基本的文件buf。它默认使用字符缓冲区,如我提供的链接中所述。如果设置truetype字体,实际上控制台是unicode的,但是除非设置适当的默认系统区域设置,否则不会启用对CJK字符的支持。@Yuhong,用于windows控制台的字符编码是al非unicode系统区域设置(又名ANSI,又名CP_ACP)。它从来不是UTF-16、UTF-8或任何其他unicode区域设置。您选择的字体中存在unicode转换表不会使控制台本身与unicode兼容。实际上,控制台的主要非unicode编码是OEMCP,而不是ACP。