1. 程式人生 > >C++實現中英文與UNICODE十六進位制字串互轉

C++實現中英文與UNICODE十六進位制字串互轉

之前搞過這個中英文與UNICODE十六進位制字串的互轉,但是發現有點小問題。現在重新搞了一個,測試中暫時沒有發現什麼問題。先記錄下來。

我嘗試使用過MultiByteToWideChar和WideCharToMultiByte來實現這個功能,但是發現不行。也就是無法實現如:

中文English  --> 4e2d65870045006e0067006c006900730068

4e2d65870045006e0067006c006900730068 --> 中文English

這麼一個轉換,上述的都是字串。

好看下面的原始碼:YCodec是自己寫的一個類

YCodec.h檔案原始碼:

#include <iostream>
using namespace std;

class YCodec
{
public:
	YCodec();
	~YCodec();
	// char to hex code
	int Char2Hex(char ch);
	// hex to char
	char Hex2Char(unsigned int n);
	// num^index
long MIndex(int num, int index); // string to hex code long String2Hex(char* string, int strlen); // hex to char* int Hex2String(long hex, char* string, int* slen); // hex to wchar_t code wchar_t Hex2Wchart(long hex); // UNICODE十六進位制字串轉成中英文 // hex string to wchar_t* int HexStr2WChars(char* hexstr, int hexstrlen, int eachchar, wchar_t* wchs, int* wchslen); // wchar_t to hex code long Wchart2Hex(wchar_t wch); // 中英文轉成UNICODE十六進位制字串 // wchar_t* to char*(hex string) int Wchart2HexStr(wchar_t* wchs, int wchslen, int eachchar, char* hexstr, int* hexstrlen); };


YCodec.cpp檔案原始碼:

#include "StdAfx.h"
#include "YCodec.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

YCodec::YCodec()
{
}

YCodec::~YCodec()
{
}


// char to hex code
// error: return -1 
int YCodec::Char2Hex(char ch)
{
	int n = -1;
	switch(ch)
	{
	case '0':	n = 0;	break;
	case '1':	n = 1;	break;
	case '2':	n = 2;	break;
	case '3':	n = 3;	break;
	case '4':	n = 4;	break;
	case '5':	n = 5;	break;
	case '6':	n = 6;	break;
	case '7':	n = 7;	break;
	case '8':	n = 8;	break;
	case '9':	n = 9;	break;
	case 'A':
	case 'a':	n = 10;	break;
	case 'B':
	case 'b':	n = 11;	break;
	case 'C':
	case 'c':	n = 12;	break;
	case 'D':
	case 'd':	n = 13;	break;
	case 'E':
	case 'e':	n = 14;	break;
	case 'F':
	case 'f':	n = 15;	break;
	default:	break;
	}

	return n;
}

// hex to char
// error: return -1 
char YCodec::Hex2Char(unsigned int n)
{
	char ch;
	if(n>=0 && n<=9)	ch = 48 + n;
	else if(n>=10 && n<=15)	ch = 65 - 10 + n;
	else ch = -1;

	return ch;
}

// num^index
long YCodec::MIndex(int num, int index) { long s = 1; int i=0; while(i<index) { s *= num; i++; } return s; } // string to hex code // error: return -1 long YCodec::String2Hex(char* string, int strlen) { long hex=-1; int i=0, n=0; char *p = string; p += strlen - 1; if(string == NULL) return hex; if(strlen <= 0 || strlen > 10) return hex; hex = 0; do { n = Char2Hex(*p--); hex += n*MIndex(16, i++); }while(i<strlen); return hex; } // hex to char* // string==NULL,slen = the size of string(slen as output) // string!=NULL,input the length of string // error: return -1 int YCodec::Hex2String(long hex, char* string, int* slen) { char tmp[11] = {0}; if(hex < 0) return -1; if(string == NULL){// count the length it will be used sprintf(tmp, "%x", hex); *slen = strlen(tmp); return 1; } memset(string, 0, *slen); sprintf(string, "%x", hex); return 1; } // hex to wchar_t code // eg: input 0x5e74, return 年 // error: return -1 wchar_t YCodec::Hex2Wchart(long hex) { wchar_t wch = -1; if(hex <0) return wch; wch = (wchar_t)hex; return wch; } // hex string to wchar_t* // UNICODE十六進位制字串轉成中英文 // hexstr每eachchar轉換為一個wchar_t // wchs == NULL, wchsLen as output(the size of wchs will be used) // error: return -1 int YCodec::HexStr2WChars(char *hexstr, int hexstrlen, int eachchar, wchar_t *wchs, int *wchsLen) { if(hexstr == NULL || hexstrlen <= 0 || eachchar <= 0) return -1; if(wchs == NULL){// count the size wchs it will be used *wchsLen = hexstrlen/eachchar + (hexstrlen%eachchar>0 ? 1 : 0); return 1; } memset(wchs, 0, *wchsLen * sizeof(wchar_t)); char* tmp = new char[eachchar+1]; char* p = hexstr; wchar_t* pwch = wchs; for(int i=0; i<hexstrlen; i+=eachchar){ memset(tmp, 0, eachchar+1); // get eachchar char for(int j=0; j<eachchar; j++){ if(i+j > hexstrlen) break; tmp[j] = *p++; } // char* to hex long hex = String2Hex(tmp, strlen(tmp)); if(hex == -1) continue; // hex to wchar_t *pwch++ = Hex2Wchart(hex); } if(tmp) delete []tmp; return 1; } // wchar_t to hex code long YCodec::Wchart2Hex(wchar_t wch) { return (long)wch; } // wchar_t* to char*(hex string) // 中英文轉成UNICODE十六進位制字串 // eachchar用於控制每個wchar_t轉換成多少個char字元 // hexstr == NULL,hexstrlen as output(the size of hexstr will be used) // error: return -1 int YCodec::Wchart2HexStr(wchar_t *wchs, int wchslen, int eachchar, char* hexstr, int* hexstrlen) { if(wchs == NULL || wchslen <= 0 || eachchar <= 0) return -1; if(hexstr == NULL){// count the size of hexstr will be used *hexstrlen = wchslen*eachchar; return 1; } memset(hexstr, 0, *hexstrlen); char* p = hexstr; wchar_t* pwch = wchs; char* tmp = new char[eachchar+1]; for(int i=0; i<wchslen; i++){ // wchar_t to hex long hex = Wchart2Hex(*pwch++); // hex to char* int charlen = 0; if(Hex2String(hex, NULL, &charlen) != -1){ char* str = new char[charlen+1]; memset(str, 0, charlen+1); int n = Hex2String(hex, str, &charlen); if(n != -1){ int k=0; memset(tmp, 0, eachchar+1); for(k=0; k<eachchar-charlen; k++) tmp[k] = '0'; tmp = strcat(tmp, str); p = strcat(p, tmp); } if(str) delete []str; } if(i > *hexstrlen) break; } if(tmp) delete []tmp; return 1; }

中英文轉unicode十六進位制字串例項:
	
	CString input;
	m_Input.GetWindowTextW(input);
	CString tmp;
	YCodec yCodec;

	// CString to wchar_t*
	int len = input.GetLength();
	wchar_t* wchs = new wchar_t[len+1];
	memset(wchs, 0, sizeof(wchar_t)*(len+1));
	wcscpy(wchs, input.GetBuffer(len) );
	// wchar_t* to hex string
	int hexlen = 0;
	if(yCodec.Wchart2HexStr(wchs, len, 4, NULL, &hexlen) != -1){
		char* hexstr = new char[hexlen+1];
		memset(hexstr, 0, hexlen+1);
		int n = yCodec.Wchart2HexStr(wchs, len, 4, hexstr, &hexlen);
		if(n != -1){
			// char* to CString
			char* p = hexstr;
			for(int i=0; i<hexlen; i++)	tmp.AppendChar(*p++);
		}
		if(hexstr)	delete []hexstr;
	}

	if(wchs)	delete []wchs;

	m_Disp.SetWindowTextW(tmp);

該功能時在MFC程式中測試的。可以做到如下效果:

輸入字串“中文English“ 轉換後輸出 ”4e2d65870045006e0067006c006900730068“字串,每個中文或英文轉成4個char型別資料。

unicode十六進位制字串轉中英文例項:

CString input;
	m_Input.GetWindowTextW(input);

	CString tmp;

	YCodec yCodec;

	// CString to char*
	int strlen = input.GetLength();
	char* str = new char[strlen+1];
	memset(str, 0, strlen+1);
	for(int i=0; i<strlen; i++)	str[i] = input.GetAt(i);
	// hex string to wchar_t*
	int wchslen = 0;
	if(yCodec.HexStr2WChars(str, strlen, 4, NULL, &wchslen) != -1){
		wchar_t* wchs = new wchar_t[wchslen+1];
		memset(wchs, 0, sizeof(wchar_t)*(wchslen+1));
		int n = yCodec.HexStr2WChars(str, strlen, 4, wchs, &wchslen);
		if(n != -1){
			// wchar_t to CString
			wchar_t* pwch = wchs;
			for(int i=0; i<wchslen; i++)	tmp.AppendChar(*pwch++);
		}
		if(wchs)	delete []wchs;
	}


	m_Disp.SetWindowTextW(tmp);


輸入字串 ”4e2d65870045006e0067006c006900730068“轉換後輸出“中文English“ 字串,每4個char型別資料轉成1箇中文或英文。

上述程式碼經測試可行,暫時沒發現什麼問題。


測試程式及原始碼:(不用分下載)