C++ 常見進制轉換代碼

C++ 進制轉換代碼記錄

一丶進制轉換

1.1 介紹

再平常寫代碼的時候經常會用到進制轉換。 比如16進制轉爲10進制。

16進制值轉爲Ascii等。所以這裏啓用一個整理。方便下次炒代碼。

代碼來源於網上以及朋友提供的。

二丶 十六進制字符串轉換爲Ascii

2.1 方法1 Char類型操作

//************************************
// Parameter: 要進行轉換的十六進制字符串
// Parameter: 十六進程字符串的長度
// Parameter: 傳出的緩衝區,結果存放在此緩衝區,請注意一定保證緩衝區大小
//************************************
void CFileOpt::Hex2Asc1(IN unsigned char *hex, IN int hexlength, OUT unsigned char *asc)
{
    for (int i = 0; i < hexlength; i++)
    {
        sprintf((char*)asc + 2 * i, "%02X", hex[i]);
    }
}

2.2 方法2 STL String操作

//************************************
// Parameter: 要進行轉換的十六進制字符串    string類型
// Return:    返回轉換後的結構字符串
//************************************
std::string HexToAsc(string hexStr)
{
    string res = "";
    unsigned char* hexDigitTable = (unsigned char*)"0123456789abcdef";
    for (int i = 0; i < hexStr.length(); i++)
    {
        unsigned char asciiDigit1 = hexDigitTable[hexStr.at(i) & 0x0f];
        unsigned char asciiDigit0 = hexDigitTable[(hexStr.at(i) & 0xf0) >> 4];
        res += asciiDigit0;
        res += asciiDigit1;
    }
    return res;
}

2.3 方法3 google寫法

這種方式是從逆向google Chrome的時候得到的。自己封裝的

當然你可以自己修改參數

//************************************
// Parameter: 要進行轉換的十六進制字符串
// Parameter: 十六進制字符串的長度
// Parameter: 傳出的string 是一個指針 外面可以傳遞 &strxxx 也可以修改爲引用
//************************************
bool Hex2Asc2(
    const unsigned char* data,
    int data_len,
    std::string* string) {
    if (!string)
        return false;

    string->clear();
    if (data_len < 1 || !data)
        return false;

    static const char kHex[] = "0123456789ABCDEF";

    // Fix the buffer size to begin with to avoid repeated re-allocation.
    string->resize(data_len * 2);
    int index = data_len;
    while (index--) {
        string->at(2 * index) = kHex[data[index] >> 4];  // high digit
        string->at(2 * index + 1) = kHex[data[index] & 0x0F];  // low digit
    }

    return true;
}

2.4 總結

上述方法命令結果爲如下

IN -> "AABB"
OUT-> "41414242"

三丶Ascii字符串轉爲16進制字符串

3.1 方法1 字符指針類型轉換

//************************************
// Parameter: 帶轉換的的Ascii編碼
// Parameter: 長度
// Parameter: 傳出結果,是一個16進制字符串。
//************************************
void asc2hex(
    IN unsigned char *asc, 
    IN int hexlength, 
    OUT unsigned char *hex)
{
    if (strlen((char*)asc) < hexlength * 2)
    {
        char *asc_temp = new char[hexlength * 2 + 1];
        memset(asc_temp, 'F', hexlength * 2 + 1);
        memcpy(asc_temp, asc, strlen((char*)asc));
        for (int i = 0; i < hexlength; i++)
        {
            char temp[3] = { asc_temp[i * 2], asc_temp[i * 2 + 1] };
            hex[i] = strtol(temp, 0, 16);
        }
        delete[]asc_temp;
    }
    else
    {
        for (int i = 0; i < hexlength; i++)
        {
            char temp[3] = { asc[i * 2], asc[i * 2 + 1] };
            hex[i] = strtol(temp, 0, 16);
        }
    }

}

四丶十六進制字符轉爲整數

4.1 方法1 字符轉爲整數

int Hex2Int(char c) {
    return (c >= '0' && c <= '9') ? (c)-'0' :
        (c >= 'A' && c <= 'F') ? (c)-'A' + 10 :
        (c >= 'a' && c <= 'f') ? (c)-'a' + 10 : 0;
}
IN -> 'F'
OUT -> 15

五丶十六進制字符串轉爲二進制

5.1 十六進制字符串轉爲二進制類型

//************************************
// Parameter: 要轉換的16進制字符串
// Parameter: 要轉換的16進制字符串大小
// Parameter: 轉換後的傳出數據
// 傳入16進制字符串 "AABB" 則 傳出數據的Buff裏面的字節則是 buf[0] = 'AA'  buf[1] = '\xBB' 字節
//************************************

void Hex2Bin(const unsigned char* hex, int sz, unsigned char* out) {
    int i;
    for (i = 0; i < sz; i += 2) {
        out[i / 2] = (Hex2Int(hex[i]) << 4) | Hex2Int(hex[i + 1]);
    }
}

5.2 二進制類型十六進制轉爲十六進制字符串

//************************************
// Parameter: 代轉換的Buff 設Buf[0] = 0xAA buf[1] = 0xBB
// Parameter: buf大小
// Parameter: 傳出結果,是一個16進制字符串。
//傳出的是"AABB"
//************************************
void Bin2Hex(const unsigned char* in, int sz, char* out) {
    int i;
    for (i = 0; i < sz; i++) {
        sprintf_s(out + (i * 2), 4, "%02x", in[i]);
    }
}

六丶10進制數字轉爲16進制字符串

公共頭文件

#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>

6.1方法1 STL版

//************************************
// Parameter: 要轉換的10進制數
// Parameter: 轉換後的結果是否添加前綴 0x 
// Parameter: 轉換後的結果是否是大寫
// 默認值返回大寫不帶前綴的十六進制字符串
//************************************
string dec2hex1(
    IN unsigned long long i, 
    IN bool isAddPrefix = false, 
    IN bool isUpcase = true)
{
    stringstream ss;

    if (isAddPrefix)
    {
        if (isUpcase)
        {
            ss << showbase << hex << uppercase << i; //prepends 0x

        }
        else
        {
            ss << showbase << hex << nouppercase << i; //prepends 0x
        }
    }
    else
    {
        if (isUpcase)
        {
            ss << hex << uppercase << i;
        }
        else
        {
            ss << hex << nouppercase << i;
        }
    }



    return ss.str();
}
//************************************
// Parameter: 要轉換的10進制數
// Parameter: 轉換後的結果是否添加前綴 0x 
// Parameter: 轉換後的結果是否是大寫
// 默認值返回大寫不帶前綴的十六進制字符串
//************************************
string dec2hex2(
    IN unsigned long long i,
    IN bool isAddPrefix = false, 
    IN bool isUpcase = true)
{
    stringstream ss;
    string s;
    if (isAddPrefix)
    {
        if (isUpcase)
        {
            ss << showbase << hex << uppercase << i; //prepends 0x

        }
        else
        {
            ss << showbase << hex << nouppercase << i; //prepends 0x
        }
    }
    else
    {
        if (isUpcase)
        {
            ss << hex << uppercase << i;
        }
        else
        {
            ss << hex << nouppercase << i;
        }
    }

    ss >> s;
    return s; 
}

6.2 方法2 C庫函數版

//************************************
// Parameter: 要轉換的10進制數
// Parameter: 轉換後的結果是否添加前綴 0x 
// Parameter: 轉換後的結果是否是大寫
// 默認值返回大寫不帶前綴的十六進制字符串
//************************************
string CFileOpt::dec2hex_c(
    IN unsigned long long i,
    IN bool isAddPrefix,
    IN bool isUpcase)
{
    if (isAddPrefix)
    {
        if (isUpcase)
        {
            char s[20];
            sprintf(s, "0X%X", i);
            return string(s);
        }
        else
        {
            char s[20];
            sprintf(s, "0x%x", i);
            return string(s);
        }
    }
    else
    {
        if (isUpcase)
        {
            char s[20];
            sprintf(s, "%X", i);
            return string(s);
        }
        else
        {
            char s[20];
            sprintf(s, "%x", i);
            return string(s);
        }
    }

    return "";
}

七丶 String和Wstring的互相轉換

7,1 WinApi方式

頭文件

#include <windows.h>
wstring string2wstring(string str)
{
    wstring result;
    //獲取緩衝區大小,並申請空間,緩衝區大小按字符計算  
    int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
    wchar_t* buffer = new wchar_t[len + 1];
    //多字節編碼轉換成寬字節編碼  
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
    buffer[len] =L'\0';             //添加字符串結尾  
    //刪除緩衝區並返回值  
    result.append(buffer);
    delete[] buffer;
    return result;
}

//將wstring轉換成string  
string wstring2string(wstring wstr)
{
    string result;
    //獲取緩衝區大小,並申請空間,緩衝區大小事按字節計算的  
    int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
    char* buffer = new char[len + 1];
    //寬字節編碼轉換成多字節編碼  
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
    buffer[len] = '\0';
    //刪除緩衝區並返回值  
    result.append(buffer);
    delete[] buffer;
    return result;
}

7.2 BSTR過渡版

#include <comutil.h>  
#pragma comment(lib, "comsuppw.lib")
 
string wstring2string(const wstring& ws)
{
    _bstr_t t = ws.c_str();  
    char* pchar = (char*)t;  
    string result = pchar;  
    return result;  
}
 
wstring string2wstring(const string& s)
{
    _bstr_t t = s.c_str();  
    wchar_t* pwchar = (wchar_t*)t;  
    wstring result = pwchar;  
    return result; 
}

7.3 CRT庫版本,平臺無關。

#include <string>
#include <locale.h>
using namespace std;
string ws2s(const wstring& ws)
{
string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
 
setlocale(LC_ALL, "chs");
 
const wchar_t* _Source = ws.c_str();
size_t _Dsize = 2 * ws.size() + 1;
char *_Dest = new char[_Dsize];
memset(_Dest,0,_Dsize);
wcstombs(_Dest,_Source,_Dsize);
string result = _Dest;
delete []_Dest;
 
setlocale(LC_ALL, curLocale.c_str());
 
return result;
}
 
wstring s2ws(const string& s)
{
setlocale(LC_ALL, "chs");
 
const char* _Source = s.c_str();
size_t _Dsize = s.size() + 1;
wchar_t *_Dest = new wchar_t[_Dsize];
wmemset(_Dest, 0, _Dsize);
mbstowcs(_Dest,_Source,_Dsize);
wstring result = _Dest;
delete []_Dest;
 
setlocale(LC_ALL, "C");
 
return result;
}

7.4 U8寬字符類型的轉換

頭文件應該是以下幾個,具體哪個我忘了索性都寫出來。可以嘗試刪除

#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <codecvt>
std::string to_byte_string(const std::wstring & input)
{
    //std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.to_bytes(input);
}

std::wstring to_wide_string(const std::string & input)
{
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.from_bytes(input);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章