字符串和十六进制数的相互转换

     通过文件进行通信的,可能遇上的问题就是文件中的字符出现乱码的问题。在网上也找了很久资料,一般都是字符串转换成十六进制,很少有转换回来的。首先根据使字符集格式分为char和wchar_t两个版本

1. char版本

std::string string_to_hex(const std::string& input)
{
    static const char* const lut = "0123456789ABCDEF";
    size_t len = input.length();

    std::string output;
    output.reserve(2 * len);
    for (size_t i = 0; i < len; ++i)
    {
        const unsigned char c = input[i];
        output.push_back(lut[c >> 4]);
        output.push_back(lut[c & 15]);
    }
    return output;
}

std::string hex_to_string(const std::string& input)
{

    static const char* const lut = "0123456789ABCDEF";
    size_t len = input.length();
    if (len & 1) throw std::invalid_argument("odd length");

    std::string output;
    output.reserve(len / 2);
    for (size_t i = 0; i < len; i += 2)
    {
        char a = input[i];
        const char* p = std::lower_bound(lut, lut + 16, a);
        if (*p != a) throw std::invalid_argument("not a hex digit");

        char b = input[i + 1];
        const char* q = std::lower_bound(lut, lut + 16, b);
        if (*q != b) throw std::invalid_argument("not a hex digit");

        output.push_back(((p - lut) << 4) | (q - lut));
    }
    return output;
}

     这是从stackoverflow上摘下来的,对于使用ASCII字符集的字符串来说没有什么问题,但对于使用2字节存储的字符就无能为力了。

2.wchar_t版本

CString ConvertWCHARToHex(CString Data)
{
    CString sResult("");
    int len = Data.GetLength();
    for (long nLoop=0; nLoop<len; nLoop++) {
        wchar_t ch = Data.GetAt(nLoop);
        //将wchar_t转换为char[2]
        char c_cn[2]={'0'};
        W2C(ch,c_cn);
        static const char *hex = "0123456789ABCDEF";
        for(int i=0;i<2;i++) {
            unsigned char chHexA = hex[((unsigned char)(c_cn[i]) >> 4) & 0x0f];
            unsigned char chHexB = hex[(unsigned char)(c_cn[i]) & 0x0f];
            sResult += (char)chHexA;
            sResult += (char)chHexB;
        }
    }

    return sResult;
}
void W2C(wchar_t w_cn, char c_cn[]) 
{ 
    c_cn[0] = w_cn >> 8 ; 
    c_cn[1] = (char)w_cn ; 
} 

CString ConvertHexToWCHAR(CString Data)
{
    wstring wstr;
    wstr.reserve(Data.GetLength() / 4);

    int i;
    for (i=0; i < Data.GetLength()/4; ++i)
    {
        int n_value = _tcstol(Data.Mid(i*4, 4), NULL, 16);
        wstr.push_back((wchar_t)n_value);
    }
    CString strResult(wstr.c_str());
    return strResult;
}

      CString的Format方法能直接格式化成十六进制的字符,但对于使用UTF8的来说就有点问题。因为UTF8完美兼容ASCII,也就是使用单字节,对于其他的字符,比如汉字,使用的又是双字节,所以转换成的十六进制就很难判断源字符是来自于单字节字符还是双字节字符。

      这里使用了CString,但对于不支持MFC的来说,重写一下也不是什么大问题。留到下次更新吧。

转载于:https://www.cnblogs.com/navono007/p/3378810.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值