C++中怎么读取UTF-8编码的文件?

时间:2023-01-05 21:03:19
求教各位大侠:

小弟要用C++读取一个UTF-8编码的文件,然后逐行打印到控制台。不知道该怎么做。
试过用宽字符解决,程序如下。但读出来的都是乱码。

#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main()
{
wifstream winf;
winf.open("test.txt");

wstring wstr;
while(getline(winf, wstr))
{
wcout << wstr << endl;
}
winf.close();
return 0;
}

书上说wchar_t和wstring等类型是支持Unicode的,但我不知道它们支不支持UTF-8。另外我将原来的UTF-8文件在Notepad中转存成Unicode编码格式,用上面的程序读取,也还是乱码,而且乱码得比UTF-8文件还严重。不明白这是为什么?

请达人们指教下,读UTF-8文件用什么方法?标准C++对此有支持么?
谢谢!

14 个解决方案

#1


标准库中没有这个东西
需要自己将文件的内容转换格式
win下用 WideCharToMultiByte MultiByteToWideChar 转换编码格式
linux下用iconv转换编码格式.

#2


达人能给出一段例子么?小弟是菜鸟,对这些不太懂~~

#3


没有代码,你搜索一下这些就能找到例子
iconv
WideCharToMultiByte
MultiByteToWideChar

#4


用C++的方法,需要自己写编码转换的方法,基本要吐血才能写好。
还是用这个简单些。
  wchar_t linex[100];
  FILE * f1;
  f1=_wfopen(L"C:\\uni.txt",L"rt+,ccs=UNICODE");  //or UTF-8
     //int fileOpen=_wfopen_s(&f1,L"C:\\uni.txt",L"rt+,ccs=UTF-8");        
       
     locale loc("");
     wcout.imbue(loc);

        while (!feof(f1))
{
 fgetws(linex,100,f1);
          wcout<<linex;
}
         fclose(f1);

#5


To HewpKanXue:
_wfopen是标准C的函数么?在C++中需要include什么头文件?

#6


<stdio.h> or <wchar.h>

#7


不是标准库函数, 在 VC 中使用有效 ...

#8


我试了下,上面给出的代码也不对~~还是会输出乱码,而且会有死循环……

#9


我用来测试的文件是用Notepad编辑并保存为UTF-8格式的,这会跟结果有关系么?
文件文本的前几位是Byte-Order Mark,这又有没有关系?

#10


我这里完全正常,没有你说的问题。
f1=_wfopen(L"C:\\uni.txt",L"rt+,ccs=UNICODE");   //for unicode 文件
f1=_wfopen(L"C:\\uni.txt",L"rt+,ccs=UTF-8");    //for UTF-8 文件。
你不是把这也搞错了吧。再看一下数组长度够不,100我随便写的。 
各种编码格式文件前面有前导标示符,你只要打开文件格式选对了,就不用管它了。

#11


To HewpKanXue:
你测试的时候有中文字符么?

我用VC编译,打开的文件中包含如下文字:

这是一个测试文件
This is a test.

运行结果为:
锘胯繖鏄竴涓祴璇曟枃浠?This is a test.Press any key to continue

…… :(

#12


把文件内的文字换成:

This is a test.
这是一个测试文件

结果则为:死循环

#13


inline void StringCodeChange(LPCTSTR _src, UINT _srcCode, string& _dest, UINT _destCode)
{
int len = MultiByteToWideChar(_srcCode , 0, _src, -1, NULL, 0); 
WCHAR* _srcTemp = new WCHAR[len]; 
MultiByteToWideChar(_srcCode , 0, _src, -1, _srcTemp, len); 
len = WideCharToMultiByte(_destCode, 0, _srcTemp, -1, NULL, 0, NULL, NULL); 
  char* _destTemp = new char[len]; 
  WideCharToMultiByte(_destCode, 0, _srcTemp, -1, _destTemp, len, NULL, NULL); 

_dest = _destTemp;

delete []_srcTemp; 
delete []_destTemp; 
}

char ss[256] = {(char)0xE8, (char)0x81, (char)0x8A, (char)0xE5, (char)0x9F, (char)0x8E, 
(char)0xE7, (char)0xAB, (char)0x99, (char)0} ; 
string s1, s2;
StringCodeChange(ss, CP_UTF8, s1, CP_ACP);
StringCodeChange(s1.c_str(), CP_ACP, s2, CP_UTF8);

#14


To oowgsoo:

THX~~
但是……这个怎么用呢?小弟菜鸟,请大侠赐教~~

#1


标准库中没有这个东西
需要自己将文件的内容转换格式
win下用 WideCharToMultiByte MultiByteToWideChar 转换编码格式
linux下用iconv转换编码格式.

#2


达人能给出一段例子么?小弟是菜鸟,对这些不太懂~~

#3


没有代码,你搜索一下这些就能找到例子
iconv
WideCharToMultiByte
MultiByteToWideChar

#4


用C++的方法,需要自己写编码转换的方法,基本要吐血才能写好。
还是用这个简单些。
  wchar_t linex[100];
  FILE * f1;
  f1=_wfopen(L"C:\\uni.txt",L"rt+,ccs=UNICODE");  //or UTF-8
     //int fileOpen=_wfopen_s(&f1,L"C:\\uni.txt",L"rt+,ccs=UTF-8");        
       
     locale loc("");
     wcout.imbue(loc);

        while (!feof(f1))
{
 fgetws(linex,100,f1);
          wcout<<linex;
}
         fclose(f1);

#5


To HewpKanXue:
_wfopen是标准C的函数么?在C++中需要include什么头文件?

#6


<stdio.h> or <wchar.h>

#7


不是标准库函数, 在 VC 中使用有效 ...

#8


我试了下,上面给出的代码也不对~~还是会输出乱码,而且会有死循环……

#9


我用来测试的文件是用Notepad编辑并保存为UTF-8格式的,这会跟结果有关系么?
文件文本的前几位是Byte-Order Mark,这又有没有关系?

#10


我这里完全正常,没有你说的问题。
f1=_wfopen(L"C:\\uni.txt",L"rt+,ccs=UNICODE");   //for unicode 文件
f1=_wfopen(L"C:\\uni.txt",L"rt+,ccs=UTF-8");    //for UTF-8 文件。
你不是把这也搞错了吧。再看一下数组长度够不,100我随便写的。 
各种编码格式文件前面有前导标示符,你只要打开文件格式选对了,就不用管它了。

#11


To HewpKanXue:
你测试的时候有中文字符么?

我用VC编译,打开的文件中包含如下文字:

这是一个测试文件
This is a test.

运行结果为:
锘胯繖鏄竴涓祴璇曟枃浠?This is a test.Press any key to continue

…… :(

#12


把文件内的文字换成:

This is a test.
这是一个测试文件

结果则为:死循环

#13


inline void StringCodeChange(LPCTSTR _src, UINT _srcCode, string& _dest, UINT _destCode)
{
int len = MultiByteToWideChar(_srcCode , 0, _src, -1, NULL, 0); 
WCHAR* _srcTemp = new WCHAR[len]; 
MultiByteToWideChar(_srcCode , 0, _src, -1, _srcTemp, len); 
len = WideCharToMultiByte(_destCode, 0, _srcTemp, -1, NULL, 0, NULL, NULL); 
  char* _destTemp = new char[len]; 
  WideCharToMultiByte(_destCode, 0, _srcTemp, -1, _destTemp, len, NULL, NULL); 

_dest = _destTemp;

delete []_srcTemp; 
delete []_destTemp; 
}

char ss[256] = {(char)0xE8, (char)0x81, (char)0x8A, (char)0xE5, (char)0x9F, (char)0x8E, 
(char)0xE7, (char)0xAB, (char)0x99, (char)0} ; 
string s1, s2;
StringCodeChange(ss, CP_UTF8, s1, CP_ACP);
StringCodeChange(s1.c_str(), CP_ACP, s2, CP_UTF8);

#14


To oowgsoo:

THX~~
但是……这个怎么用呢?小弟菜鸟,请大侠赐教~~