C++ Can';t从文件中读取unicode(日语)
嗨,我有一个包含日语文本的文件,保存为unicode文件 我需要读取文件并将信息显示到标准输出 我正在使用VisualStudio2008C++ 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
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-8char*
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。