Ubuntu/linux c开发(1) GB2312/UTF8相互转换

2023-05-16

由于工作原因最近开始搞linux开发,写几个服务程序。编码格式的转换算是基础之一。网上也有现成的代码,只是有一些小问题需要注意,这里自己保存一下:
1、判断字符是否是utf8字符

// 判断字符串是否是utf8
is_str_utf8
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;
}

2、下面是 GB2312/UTF8相互转换
重点: if(-1 == (int)iconv(cd, src, &iSrcLen, dst, &iDstLen)) { iconv_close(cd);return -1;} 原先网上没有iconv_close(cd),会导致内存泄漏

//GB2312-》UTF8
int GB2312ToUTF8(char* szSrc, size_t iSrcLen, char* szDst, size_t iDstLen)
{
	if (is_str_utf8((const char*)szSrc))
	{
		sprintf(szDst,"%s",szSrc);
		return 0;
	}
	
	iconv_t cd = iconv_open("utf-8//IGNORE", "gb2312//IGNORE");
	if(0 == cd)
		return -2;
	memset(szDst, 0, iDstLen);
	char **src = &szSrc;
	char **dst = &szDst;
	if(-1 == (int)iconv(cd, src, &iSrcLen, dst, &iDstLen))
	{	iconv_close(cd);return -1;}
	iconv_close(cd);
	return 0;
}

//UTF8->GB2312
int UTF8ToGB2312(char* szSrc, size_t iSrcLen, char* szDst, size_t iDstLen)
{
	iconv_t cd = iconv_open("gb2312//IGNORE", "utf-8//IGNORE");   // take care of "//IGNORE", it will ignore those invalid code
	if(0 == cd)
		return -2;
	memset(szDst, 0, iDstLen);
	char **src = &szSrc;
	char **dst = &szDst;
	if(-1 == (int)iconv(cd, src, &iSrcLen, dst, &iDstLen))
	{	iconv_close(cd);return -1;}
	iconv_close(cd);
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ubuntu/linux c开发(1) GB2312/UTF8相互转换 的相关文章

随机推荐