Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

[C/C++]_[utf8字符串转换为unicode字符串]

$
0
0


场景:

1.windows下需要unicode来处理非ascii的字符,如中文文件路径.

2.但是做字符串处理时又需要转换成中间的utf8处理,这就涉及到了互转.

3.参考unicode和utf8关系:


http://baike.baidu.com/view/40801.htm


文件:test_utf82unicode.cpp(只做了支持双字节的unicode转码.)

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

void OneUTF82Unicode(const char* utf_char, char* unicode_char);

char* utf82unicode(const char* utf,size_t *unicode_number)
{	
	char* utf8 = strdup(utf);
	size_t utf8_length = strlen(utf8); 
	char* unicode = (char*)malloc(utf8_length);//这里可以自己考虑实现更精确的大小.
	size_t index  = 0;
	size_t start = 0;
	unsigned char temp;
	//10000000=0x80 1110=0xE 110=0x6
	unsigned char flag = 0;
	size_t unicode_index = 0;
	bool is_finded = false;
	while((temp = utf8[index]))
	{
		start = index;

		temp = temp >> 4 ;
		if(temp > 0xE)
		{
			assert(0);
			printf("utf8 bigger than 4 byte is not supported.\n");
			break;
		}

		if(temp == 0xE)
		{
			index+=3;
			is_finded = true;
		}

		temp = temp >> 1;
		if(!is_finded && temp == 0x6)
		{
			index+=2;
			is_finded = true;
		}

		temp = temp >> 2;
		if(!is_finded && temp == 0x00)
		{
			index+=1;
			is_finded = true;
		}

		if(index > utf8_length)
		{
			break;
		}
		flag = utf8[index];
		utf8[index] = 0;
		OneUTF82Unicode(utf8+start,unicode+unicode_index);
		utf8[index] = flag;
		unicode_index+=2;
		is_finded = false;
	}
	free(utf8);
	*unicode_number = unicode_index/2;
	return unicode;
}

void OneUTF82Unicode(const char* utf_char, char* unicode_char)
{
	//unicode: 0x192->110010010 ,utf8:0xC692->11000110|10010010
	//小端序
	int utf_length = strlen(utf_char);
	//0x3F->00111111
	switch(utf_length)
	{
		case 1: 
			unicode_char[0] = utf_char[0];
			unicode_char[1] = 0;
			break;
		case 2: 
			unicode_char[0] = (utf_char[1] & 0x3F) | ((utf_char[0] & 0x3) << 6);
			unicode_char[1] = (utf_char[0] & 0x3C) >> 2;
			break;
		case 3: 
			unicode_char[0] = (utf_char[2] & 0x3F) | ((utf_char[1] & 0x3) << 6);
			unicode_char[1] = ((utf_char[1] & 0x3C) >> 2) | ((utf_char[0] & 0xF) << 4);
			break;
		default:
			assert(0);
			printf("utf_char length is bigger than 4 unsupported.\n");
			break;
	}
}

int main(int argc, char *argv[])
{
	printf("Hello, world\n");
	char utf_char[12] = {0xC3,0xBE};
	memset(utf_char+2,0,10);

	char unicode_char[3] = {0,0,0};
	OneUTF82Unicode(utf_char,unicode_char);
	printf("%x,%x\n",(unsigned char)unicode_char[0],unicode_char[1]);

	utf_char[0] = 0xE6;
	utf_char[1] = 0x88;
	utf_char[2] = 0x91;

	OneUTF82Unicode(utf_char,unicode_char);
	printf("%x,%x\n",(unsigned char)unicode_char[0],unicode_char[1]);

	size_t unicode_number = 0;
	char utf_str[]={0xC3,0xBE,0xE6,0x88,0x91,0xE4,0xBB,0xAC,0xE7,0x9A,0x84,0xE5,0x9B,
		0xBD,0xE5,0xAE,0xB6,0x64,0x61,0xE7,0x9A,0x84,0xE5,0x93,0xA6};
	char* unicode = utf82unicode(utf_str,&unicode_number);
	
	printf("%d\n",unicode_number);
	size_t index = 0;
	for(size_t i=0;i<unicode_number;++i,index+=2)
	{
		printf("%x,%x\n",(unsigned char)unicode[index],(unsigned char)unicode[index+1]);		
	}
	free(unicode);
	return 0;
}

Hello, world
fe,0
11,62
10
fe,0
11,62
ec,4e
84,76
fd,56
b6,5b
64,0
61,0
84,76
e6,54


作者:infoworld 发表于2013-1-27 22:10:02 原文链接
阅读:62 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>