C语言判断读取的文件内容字符编码是UTF-8还是GBK

自定义两个字符编码判断函数

bool is_str_utf8(const char* str);
bool is_str_gbk(const char* str);

测试文件

在这里插入图片描述

代码详细:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

bool is_str_utf8(const char* str);
bool is_str_gbk(const char* str);

//判断是否是UTF-8
bool is_str_utf8(const char* str)
{
	unsigned int nBytes = 0;//UFT8可用1-6个字节编码,ASCII用一个字节
	unsigned char chr = *str;
	bool bAllAscii = true;
	for (unsigned int i = 0; str[i] != '\0'; ++i) {
		chr = *(str + i);
		//判断是否ASCII编码,如果不是,说明有可能是UTF8,ASCII用7位编码,最高位标记为0,0xxxxxxx
		if (nBytes == 0 && (chr & 0x80) != 0) {
			bAllAscii = false;
		}
		if (nBytes == 0) {
			//如果不是ASCII码,应该是多字节符,计算字节数
			if (chr >= 0x80) {
				if (chr >= 0xFC && chr <= 0xFD) {
					nBytes = 6;
				}
				else if (chr >= 0xF8) {
					nBytes = 5;
				}
				else if (chr >= 0xF0) {
					nBytes = 4;
				}
				else if (chr >= 0xE0) {
					nBytes = 3;
				}
				else if (chr >= 0xC0) {
					nBytes = 2;
				}
				else {
					return false;
				}
				nBytes--;
			}
		}
		else {
			//多字节符的非首字节,应为 10xxxxxx
			if ((chr & 0xC0) != 0x80) {
				return false;
			}
			//减到为零为止
			nBytes--;
		}
	}
	//违返UTF8编码规则
	if (nBytes != 0) {
		return false;
	}
	if (bAllAscii) { //如果全部都是ASCII, 也是UTF8
		return true;
	}
	return true;
}

//判断是否是GBK
bool is_str_gbk(const char* str)
{
	unsigned int nBytes = 0;//GBK可用1-2个字节编码,中文两个 ,英文一个
	unsigned char chr = *str;
	bool bAllAscii = true; //如果全部都是ASCII,
	for (unsigned int i = 0; str[i] != '\0'; ++i) {
		chr = *(str + i);
		if ((chr & 0x80) != 0 && nBytes == 0) {// 判断是否ASCII编码,如果不是,说明有可能是GBK
			bAllAscii = false;
		}
		if (nBytes == 0) {
			if (chr >= 0x80) {
				if (chr >= 0x81 && chr <= 0xFE) {
					nBytes = +2;
				}
				else {
					return false;
				}
				nBytes--;
			}
		}
		else {
			if (chr < 0x40 || chr>0xFE) {
				return false;
			}
			nBytes--;
		}//else end
	}
	if (nBytes != 0) {   //违返规则
		return false;
	}
	if (bAllAscii) { //如果全部都是ASCII, 也是GBK
		return true;
	}
	return true;
}

//读取文件
void read_text(const char* file_name)
{
	char line[1024] = { 0 };
	FILE *file = fopen(file_name, "rt");
	if (!file)
		return;
	while (1)
	{
		//文件读取结束
		if (EOF == fscanf(file, "%s", line))
			break;
		printf("%s\n", line);
	}
	printf("%d\n", is_str_utf8(line)); 
	printf("%d\n", is_str_gbk(line));
	
	fclose(file);

}

//主函数测试
int main() {
	read_text("test.txt");
	return 0;
}

结果

在这里插入图片描述
=欢迎留言指正~=

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果不想使用 `iconv` 库函数,可以手动实现 UTF-8GBK 的转换。具体思路如下: 1. 读取 UTF-8 编码中的一个字符,根据字符编码范围确定其对应的 Unicode 编码。 2. 根据 Unicode 编码查找对应的 GBK 编码,将 GBK 编码写入输出缓存。 3. 重复上述步骤,直到所有字符都被转换为 GBK 编码。 实现代码如下: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> int utf8_to_gbk(char *inbuf, size_t inlen, char *outbuf, size_t outlen) { unsigned char *pin = (unsigned char *)inbuf; unsigned char *pout = (unsigned char *)outbuf; unsigned char *pend = (unsigned char *)inbuf + inlen; unsigned char *pstart = pout; unsigned int uc, gbk; while (pin < pend) { if (*pin < 0x80) { // 单字节字符,直接转换 *pout++ = *pin++; } else if (*pin < 0xE0) { // 双字节字符 uc = (*pin++ & 0x1F) << 6; uc |= (*pin++ & 0x3F); gbk = 0; if (uc >= 0x410 && uc <= 0x4FE) { gbk = uc - 0x350; } else if (uc >= 0x2010 && uc <= 0x2017) { gbk = uc - 0x16A0; } else if (uc >= 0x25A0 && uc <= 0x25A1) { gbk = uc - 0x1F00; } else if (uc == 0x2018) { gbk = 0xA1; } else if (uc == 0x2019) { gbk = 0xA2; } else if (uc == 0x201C) { gbk = 0xB1; } else if (uc == 0x201D) { gbk = 0xB2; } if (gbk != 0) { *pout++ = gbk >> 8; *pout++ = gbk & 0xFF; } } else { // 三字节字符,暂不支持 return -1; } if (pout - pstart >= outlen) { // 输出缓存不足 return -1; } } *pout = '\0'; return pout - pstart; } int main() { char *utf8_str = "你好,世界!"; char gbk_str[50]; if (utf8_to_gbk(utf8_str, strlen(utf8_str), gbk_str, sizeof(gbk_str)) != -1) { printf("GBK string: %s\n", gbk_str); } return 0; } ``` 需要注意的是,这个实现方法并不能支持所有的 UTF-8 字符,只支持常用的汉字和标点符号。如果需要支持更多的字符,需要对转换函数进行相应的修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值