C++读取文件,避免中文乱码,自动识别UTF8编码还是GBK编码

测试了两个文件,分别是GBK编码和UTF8编码,常规读入UTF8编码会乱码,所以第一步先识别是什么编码,再对应的读取输出即可。
测试数据:https://download.csdn.net/download/weixin_42727069/87873461
在这里插入图片描述
在这里插入图片描述


#include <iostream>
#include <fstream>
#include <string>

#include <locale>
#include <codecvt>


using namespace std;


std::wstring utf8str2wstring(const std::string str)
{
	//UTF8转宽字节
	static std::wstring_convert<std::codecvt_utf8<wchar_t>> strCnv;
	return strCnv.from_bytes(str);
}

std::wstring ANSIstri2wstring(const std::string str, const std::string locale = "Chinese")
{//GBK转宽字节
	typedef std::codecvt_byname<wchar_t, char, std::mbstate_t> F;
	static std::wstring_convert<F> strCnv(new F(locale));
	return strCnv.from_bytes(str);
}

std::string wstring2ANSIstr(const std::wstring str, const std::string locale = "Chinese")
{//宽字节转GBK
	typedef std::codecvt_byname<wchar_t, char, std::mbstate_t> F;
	static std::wstring_convert<F> strCnv(new F(locale));
	return strCnv.to_bytes(str);
}

std::string wstring2utf8str(const std::wstring str)
{//宽字节转UTF8
	static std::wstring_convert<std::codecvt_utf8<wchar_t>> strCnv;
	return strCnv.to_bytes(str);
}

void gbkToUtf8(char* UTF8, char* GBK)
{
	wstring Temp_WS = utf8str2wstring(UTF8);//转换成宽字节
	string result_GBK = wstring2ANSIstr(Temp_WS);//宽字节转换成GBK
	sprintf(GBK, "%s", result_GBK.c_str());
	return;
}
void ReadFile_GBK(const char* FileName)
{
	FILE* fp = fopen(FileName, "r");
	if (fp == NULL)
	{
		return;

	}
	char Temp[2048];

	while (EOF != fscanf(fp, "%s\n", Temp))
	{

		printf("%s\n", Temp);

	}
}

void utf8ToGbk(char* UTF8,char* GBK)
{
	wstring Temp_WS = utf8str2wstring(UTF8);//转换成宽字节
	string result_GBK = wstring2ANSIstr(Temp_WS);//宽字节转换成GBK
	sprintf(GBK, "%s", result_GBK.c_str());
	return ;
}

void ReadFile_UTF8(const char* FileName)
{
	FILE* fp = fopen(FileName, "r");
	if (fp == NULL)
	{
		return;

	}
	char Temp[2048];
	char Temp2[2048];
	while (EOF != fscanf(fp, "%s\n", Temp))
	{
		utf8ToGbk(Temp,Temp2);
		printf("%s\n", Temp2);
	}
}

void ReadFile(const char* FileName,const char* Encoding)
{//读文件,避免中文乱码
	if (strcmp(Encoding ,"UTF-8")==0)
	{
		return ReadFile_UTF8(FileName);
		
	}
	return ReadFile_GBK(FileName);

}


string detectEncoding(string fileName) 
{//解析出文件到底是GBK还是UTF8编码
	ifstream ifs(fileName);
	if (!ifs) {
		cerr << "打开文件失败!" << endl;
		return "";
	}

	int utf8Count = 0;
	int gbkCount = 0;
	string line;
	for (int i = 0; i < 5 && getline(ifs, line); i++) {
		for (int j = 0; j < line.length(); j++) {
			unsigned char c = (unsigned char)line[j];
			if (c >= 0x80) {  // 除去ASCII码
				if (c <= 0xBF) utf8Count++;
				else if (c >= 0x81 && c <= 0xFE) gbkCount++;
			}
		}
	}

	if (utf8Count > gbkCount * 3) return "UTF-8";
	else if (gbkCount > utf8Count * 3) return "GBK";
	else return "UTF-8";
}



int main()
{
	const char* fileName = "D:/te/domTiffList中文UTF8.txt";
	const char* fileName2 = "D:/te/domTiffList中文ANSI.txt";

	string encoding1 = detectEncoding(fileName);
	cout << "fileName文件编码为:" << encoding1 << endl;

	string encoding2 = detectEncoding(fileName2);
	cout << "fileName2文件编码为:" << encoding2 << endl;

	//printf("Read UTF8 File!\n");
	ReadFile(fileName, encoding1.c_str());
	ReadFile(fileName2, encoding2.c_str());




	return 0;

}

避免遗忘,特此记录——辉 2023.6.6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值