基于C/C++的UTF-8转GBK,补充中文符号的乱码

50 篇文章 1 订阅
29 篇文章 1 订阅

     最近老遇到C/C++中中文汉字或符号 编码的问题,网上的大部分资料都是依赖第三方的库来解决的,这里给大家分享一个非库函数实现的编码转换补充。 

 

接着上篇博文的GB2313的简体中文表,最后再添加上缺失的中文标点符号。

  const unsigned short gb2312table[20902] ={
   //补充中文标点:多了 19 个
    0xa1ef,//★
    0xa3ba, 0xa3ac, 0xa1a3, 0xa1a2,//冒号、逗号、句号、顿号::,。、
    0xa1b6, 0xa1b7,//书名号:《》
    0xa3bf, 0xa3a1,//问号、感叹号:?!
    0xa1b0, 0xa1b1,//双引号:“”
    0xa3a8, 0xa3a9,//括号:()
    0xa3db, 0xa3dd,//中括号:【】
    0xa3bb, 0xa1e6,//分号、摄氏度:
    0xa3a4, 0xa1ad,//人民币、省略号半个:¥…
}

   具体值可参考上篇博文GB2312简体中文附录

         GB2312简体中文编码表 GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集--基本集》,由国家标准总局发 布,1981年5月1日实施,通行于大陆。新加坡等地也使用此编码。 GB2312收录简化汉字及符号、字母、日文假名等共7445个图形字符,其中汉字占6763个。GB2312规定"对任意一个图形字符 都采用两个字节表示,每个字节均采用七位编码表示",习惯上称第一个字节为"高字节",第二个字节为"低字节"。 GB2312-80包含了大部分常用的一、二级汉字,和9区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中 文字符集,这也是最基本的中文字符集。其编码范围是高位0xa1-0xfe,低位也是0xa1-0xfe;汉字从0xb0a1开始,结束于 0xf7fe。 

修正对应关系: 

static unsigned short chinese_code(unsigned short unicode)
{
	if ((unicode >= 0x4e00) && (unicode < 0x9fa6))
		return (unicode - 0x4e00);
	else if (unicode == 0xff1a) //冒号
		return 20903;
	else if (unicode == 0xff0c) //逗号
		return 20904;
	else if (unicode == 0x3002) //句号
		return 20905;
	else if (unicode == 0x3001) //顿号
		return 20906;
	else if (unicode == 0x300a) //《
		return 20907;
	else if (unicode == 0x300b) //》
		return 20908;
	else if (unicode == 0xff1f) //?
		return 20909;
	else if (unicode == 0xff01) //!
		return 20910;
	else if (unicode == 0x201c) //“
		return 20911;
	else if (unicode == 0x201d) //”	
		return 20912;
	else if (unicode == 0xff08) //(	
		return 20913;
	else if (unicode == 0xff09) //)
		return 20914;
	else if (unicode == 0x3010) //【	
		return 20915;
	else if (unicode == 0x3011) //】
		return 20916;
	else if (unicode == 0xff1b) //分号
		return 20917;
	else if (unicode == 0x2103) //摄氏度
		return 20918;
	else if (unicode == 0xffe5) //人民币
		return 20919;
	else if (unicode == 0x2026) //省略号
		return 20920;
	else
		return 20902;
}

修正转换函数: 

static char pszBufOut[4300];
char* GBK_Format(const unsigned char* pszBufIn)
{
	int i = 0;
	int j = 0, nLen;
	unsigned short unicode;
	unsigned short gbk;
	int nBufInLen = 0;
	if (pszBufIn == NULL) 
		return NULL;
	nBufInLen = strlen((char*)pszBufIn);
	for(; i < nBufInLen; i++, j++)
	{
		if((pszBufIn[i] & 0x80) == 0x00)
		{
			nLen = 1;
			pszBufOut[j]= pszBufIn[i];
		}
		else if ((pszBufIn[i] & 0xF0) == 0xE0)
		{
 
			if (i+ 2 >= nBufInLen) return NULL;
			unicode = (((int)(pszBufIn[i] & 0x0F)) << 12) | (((int)(pszBufIn[i+1] & 0x3F)) << 6) | (pszBufIn[i+2]  & 0x3F); 
			gbk = gb2312table[chinese_code(unicode )];
			pszBufOut[j]= gbk/256;
			pszBufOut[j+1] = gbk%256;
			j++;
			i+=2;
		}
		else
		{
			return NULL;
		}
	}
	return pszBufOut;
}

最后得到如下结果: 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 将UTF-8编码换为ANSI编码是一种常见的换需求。UTF-8是一种变长编码方式,能够表示全球各种文字字符,而ANSI则是一种单字节编码,通常用于英语等西方语言。下面是一种将UTF-8换为ANSI的方法: 1. 首先,明确一点,UTF-8编码中的字符可能需要多个字节来表示,而ANSI编码只需要一个字节。因此,在换过程中,如果UTF-8编码中的字符超出了ANSI编码范围,将无法直接进行换。 2. 创建一个空字符串,用于存储换后的ANSI编码。 3. 遍历UTF-8编码的每个字节: - 如果字节的最高位是0,表示该字节单独可以表示一个ANSI字符,直接将该字节添加到ANSI编码中。 - 如果字节的最高位是1,表示该字节与后续的字节一起组成一个UTF-8字符。读取后续的字节,构成完整的UTF-8字符。 - 判断UTF-8字符是否超出了ANSI编码范围。如果超出了,则不能进行换。 - 如果没有超出ANSI编码范围,找到对应的ANSI字符,将其添加到ANSI编码中。 4. 返回换后的ANSI编码。 需要注意的是,由于ANSI编码只能表示一部分字符,因此某些UTF-8字符可能无法换为对应的ANSI字符。在实际换时,可能需要根据具体的需求和使用环境进行处理和调整。 ### 回答2: C和UTF-8是不同的字符编码标准。C是一种早期的编程语言,它使用的是ANSI字符集作为默认的字符编码。ANSI字符集使用1个字节来表示一个字符,总共有256个字符,包括标点符号、数字和一些基本的拉丁字母。UTF-8是一种现代的字符编码标准,它是Unicode的一种实现方式,使用1到4个字节来表示一个字符,总共可以表示超过1百万个字符。 要将UTF-8编码的字符换为ANSI编码,需要注意的是ANSI字符集无法表示一些特殊的字符,因此一些不在ANSI字符集中的字符可能会丢失或替换为问号或其他无效字符。可以使用一些文本编辑软件或编程语言提供的换函数来实现这个换过程。 然而,需要注意的是,由于ANSI字符集的限制和UTF-8编码字符集的广泛使用,将UTF-8换为ANSI可能会导致信息的丢失或错误的表示,特别是对于包含非拉丁字母或特殊符号的文本。因此,更推荐使用支持UTF-8的字符编码,以保留原始文本的完整性和准确性。 ### 回答3: 将UTF-8编码换为ANSI编码需要使用特定的软件或工具。由于UTF-8编码包含了更多的字符和字符集,而ANSI编码只包含较少的字符集,所以换时可能会有一些字符无法换或出现码的情况。 首先,可以使用一些文本编辑器软件来进行这种换。比如在Windows操作系统中,可以使用记事本打开UTF-8编码的文本文件,然后选择“另存为”选项,将编码格式选择为ANSI,然后保存即可。这样就将UTF-8编码换为了ANSI编码。但需要注意的是,如果文本中包含某些特殊字符,换后可能会出现码或字符丢失的情况。 另外,也可以使用一些第三方的编码换工具来进行换。这些工具可以将UTF-8编码的文本文件导入,然后选择换为ANSI编码,最后保存换后的文件。这种方式相对来说更加灵活,可以对特定字符进行自定义的换设置。 无论是使用文本编辑器还是编码换工具,都需要注意换后的结果可能不完全准确,特别是对于一些特殊字符和格式的处理。因此,在进行编码换时,应该仔细检查换后的文件,确保没有出现码或字符丢失的情况。对于一些重要的数据和文件,最好备份原始的UTF-8编码版本,以防止换后无法还原的情况发生。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ya土豆儿~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值