小弟要用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转换编码格式.
需要自己将文件的内容转换格式
win下用 WideCharToMultiByte MultiByteToWideChar 转换编码格式
linux下用iconv转换编码格式.
#2
达人能给出一段例子么?小弟是菜鸟,对这些不太懂~~
#3
没有代码,你搜索一下这些就能找到例子
iconv
WideCharToMultiByte
MultiByteToWideChar
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);
还是用这个简单些。
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什么头文件?
_wfopen是标准C的函数么?在C++中需要include什么头文件?
#6
<stdio.h> or <wchar.h>
#7
不是标准库函数, 在 VC 中使用有效 ...
#8
我试了下,上面给出的代码也不对~~还是会输出乱码,而且会有死循环……
#9
我用来测试的文件是用Notepad编辑并保存为UTF-8格式的,这会跟结果有关系么?
文件文本的前几位是Byte-Order Mark,这又有没有关系?
文件文本的前几位是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我随便写的。
各种编码格式文件前面有前导标示符,你只要打开文件格式选对了,就不用管它了。
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
…… :(
你测试的时候有中文字符么?
我用VC编译,打开的文件中包含如下文字:
这是一个测试文件
This is a test.
运行结果为:
锘胯繖鏄竴涓祴璇曟枃浠?This is a test.Press any key to continue
…… :(
#12
把文件内的文字换成:
This is a test.
这是一个测试文件
结果则为:死循环
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);
{
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~~
但是……这个怎么用呢?小弟菜鸟,请大侠赐教~~
THX~~
但是……这个怎么用呢?小弟菜鸟,请大侠赐教~~
#1
标准库中没有这个东西
需要自己将文件的内容转换格式
win下用 WideCharToMultiByte MultiByteToWideChar 转换编码格式
linux下用iconv转换编码格式.
需要自己将文件的内容转换格式
win下用 WideCharToMultiByte MultiByteToWideChar 转换编码格式
linux下用iconv转换编码格式.
#2
达人能给出一段例子么?小弟是菜鸟,对这些不太懂~~
#3
没有代码,你搜索一下这些就能找到例子
iconv
WideCharToMultiByte
MultiByteToWideChar
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);
还是用这个简单些。
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什么头文件?
_wfopen是标准C的函数么?在C++中需要include什么头文件?
#6
<stdio.h> or <wchar.h>
#7
不是标准库函数, 在 VC 中使用有效 ...
#8
我试了下,上面给出的代码也不对~~还是会输出乱码,而且会有死循环……
#9
我用来测试的文件是用Notepad编辑并保存为UTF-8格式的,这会跟结果有关系么?
文件文本的前几位是Byte-Order Mark,这又有没有关系?
文件文本的前几位是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我随便写的。
各种编码格式文件前面有前导标示符,你只要打开文件格式选对了,就不用管它了。
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
…… :(
你测试的时候有中文字符么?
我用VC编译,打开的文件中包含如下文字:
这是一个测试文件
This is a test.
运行结果为:
锘胯繖鏄竴涓祴璇曟枃浠?This is a test.Press any key to continue
…… :(
#12
把文件内的文字换成:
This is a test.
这是一个测试文件
结果则为:死循环
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);
{
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~~
但是……这个怎么用呢?小弟菜鸟,请大侠赐教~~
THX~~
但是……这个怎么用呢?小弟菜鸟,请大侠赐教~~