C++實現中英文與UNICODE十六進位制字串互轉
阿新 • • 發佈:2018-12-30
之前搞過這個中英文與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箇中文或英文。
上述程式碼經測試可行,暫時沒發現什麼問題。
測試程式及原始碼:(不用分下載)