- 一、十六进制字符数组转字符串c++
- 二、char字符转字符串
- 三、字符串转十六进制字符数组
- 四、EncodingUtil Windows平台用编码格式相互转换类
- 五、Base64Util编解码
- 六、char字符与十六进制字符互转
- 七、StringPiece.h
- ifndef MUDUO_BASE_STRINGPIECE_H
- define MUDUO_BASE_STRINGPIECE_H
- include
- include
// for ostream forward-declaration - include “muduo/base/Types.h”
- define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp) \
- undef STRINGPIECE_BINARY_PREDICATE
- ifdef HAVE_TYPE_TRAITS
- endif
- endif // MUDUO_BASE_STRINGPIECE_H
- 八、十进制转十六进制 c语言
- 九、十进制转十六进制 c语言
- 十、十进制转十六进制 c++
一、十六进制字符数组转字符串c++
string DevAnalysis::bytestohexstring(char* bytes, int bytelength)
{
string str("");
string str2("0123456789abcdef");
for (int i = 0; i < bytelength; i++)
{
int b_h = (bytes[i] & 0xf0) >> 4;
char s1 = str2.at(b_h);
str.append(1, str2.at(b_h));
int b_l = bytes[i] & 0x0f;
str.append(1, str2.at(b_l));
char s2 = str2.at(b_l);
}
return str;
}
二、char字符转字符串
char cMac[32] = { 0 };
sprintf(cMac, "%02x%02x%02x%02x%02x%02x", devinfo.m_network.mac[0], devinfo.m_network.mac[1], devinfo.m_network.mac[2], devinfo.m_network.mac[3], devinfo.m_network.mac[4], devinfo.m_network.mac[5]);
string sMac = cMac;
三、字符串转十六进制字符数组
int DevManger::TransforEdid(string& sEdid,unsigned char* pEdid)
{
char* point = NULL;
int ret = 0;
int offset = 0;
int str_len = 0;
char temp_buff[3] = { 0, 0, 0 };
if ((eCompare_Equal != sEdid.compare("")) && pEdid)
{
str_len = strlen(sEdid.data());
if ((str_len >= (128 * 2)) && (str_len <= (256 * 2)))
{
for (point = (char*)sEdid.data(), offset = 0; offset < (str_len / 2); offset++)
{
temp_buff[0] = *point;
temp_buff[1] = *(point + 1);
sscanf(temp_buff, "%2x", &pEdid[offset]);
point += 2;
}
return SUCCESS;
}
return ERROR_STATS;
}
return ERROR_STATS;
}
四、EncodingUtil Windows平台用编码格式相互转换类
/**
* Windows平台用编码格式相互转换类, EncodingUtil.h
* zhangyl 2017.03.29
**/
#ifndef __ENCODE_H__
#define __ENCODE_H__
//#ifdef ENCODE_EXPORTS
//#define ENCODE_API __declspec(dllexport)
//#else
//#define ENCODE_API __declspec(dllimport)
//#endif
#include <string>
#define ENCODE_API
class ENCODE_API EncodeUtil
{
public:
//===BEGIN: 注意:以下6个函数,需要在外部释放返回的字符串指针,否则会有内存泄露
static wchar_t* AnsiToUnicode(const char* lpszStr);
static char* UnicodeToAnsi(const wchar_t* lpszStr);
static char* AnsiToUtf8(const char* lpszStr);
static char* Utf8ToAnsi(const char* lpszStr);
static char* UnicodeToUtf8(const wchar_t* lpszStr);
static wchar_t* Utf8ToUnicode(const char* lpszStr);
//===END: 注意:以下6个函数,需要在外部释放返回的字符串指针,否则会有内存泄露
//===BEGIN: 以下函数第一个参数是需要转换的源字符串指针,第二个参数是存放转换后的目标缓冲区指针,第三个参数是目标缓冲区的大小
static bool AnsiToUnicode(const char* lpszAnsi, wchar_t* lpszUnicode, int nLen);
static bool UnicodeToAnsi(const wchar_t* lpszUnicode, char* lpszAnsi, int nLen);
static bool AnsiToUtf8(const char* lpszAnsi, char* lpszUtf8, int nLen);
static bool Utf8ToAnsi(const char* lpszUtf8, char* lpszAnsi, int nLen);
static bool UnicodeToUtf8(const wchar_t* lpszUnicode, char* lpszUtf8, int nLen);
static bool Utf8ToUnicode(const char* lpszUtf8, wchar_t* lpszUnicode, int nLen);
//===END: 以下函数第一个参数是需要转换的源字符串指针,第二个参数是存放转换后的目标缓冲区指针,第三个参数是目标缓冲区的大小
static std::wstring AnsiToUnicode(const std::string& strAnsi);
static std::string UnicodeToAnsi(const std::wstring& strUnicode);
static std::string AnsiToUtf8(const std::string& strAnsi);
static std::string Utf8ToAnsi(const std::string& strUtf8);
static std::string UnicodeToUtf8(const std::wstring& strUnicode);
static std::wstring Utf8ToUnicode(const std::string& strUtf8);
static void DecodeQuotedPrintable(const char* pSrc, char* pDest);
static bool UTF8ToUnicode(const char* pszUTF8, std::wstring& strDest);
static bool GB2312ToUnicode(const char* pszGB2312, std::wstring& strDest);
static bool UnicodeToGB2312(const wchar_t* pszUnicode, std::string& strDest);
static std::string ws2s(const std::wstring& ws);
static std::wstring s2ws(const std::string& s);
private:
EncodeUtil() = delete;
~EncodeUtil() = delete;
EncodeUtil(const EncodeUtil& rhs) = delete;
EncodeUtil& operator=(const EncodeUtil& rhs) = delete;
};
#endif // !__ENCODE_H__
/**
* Windows平台用编码格式相互转换类, EncodingUtil.cpp
* zhangyl 2017.03.29
**/
//#include "stdafx.h"
#include <locale.h>
#include <Windows.h>
//#include <iconv.h> //linux only
#include "EncodeUtil.h"
wchar_t* EncodeUtil::AnsiToUnicode(const char* lpszStr)
{
wchar_t* lpUnicode;
int nLen;
if (NULL == lpszStr)
return NULL;
nLen = ::MultiByteToWideChar(CP_ACP, 0, lpszStr, -1, NULL, 0);
if (0 == nLen)
return NULL;
lpUnicode = new wchar_t[nLen + 1];
if (NULL == lpUnicode)
return NULL;
memset(lpUnicode, 0, sizeof(wchar_t) * (nLen + 1));
nLen = ::MultiByteToWideChar(CP_ACP, 0, lpszStr, -1, lpUnicode, nLen);
if (0 == nLen)
{
delete[]lpUnicode;
return NULL;
}
return lpUnicode;
}
char* EncodeUtil::UnicodeToAnsi(const wchar_t* lpszStr)
{
char* lpAnsi;
int nLen;
if (NULL == lpszStr)
return NULL;
nLen = ::WideCharToMultiByte(CP_ACP, 0, lpszStr, -1, NULL, 0, NULL, NULL);
if (0 == nLen)
return NULL;
lpAnsi = new char[nLen + 1];
if (NULL == lpAnsi)
return NULL;
memset(lpAnsi, 0, nLen + 1);
nLen = ::WideCharToMultiByte(CP_ACP, 0, lpszStr, -1, lpAnsi, nLen, NULL, NULL);
if (0 == nLen)
{
delete[]lpAnsi;
return NULL;
}
return lpAnsi;
}
char* EncodeUtil::AnsiToUtf8(const char* lpszStr)
{
wchar_t* lpUnicode;
char* lpUtf8;
int nLen;
if (NULL == lpszStr)
return NULL;
nLen = ::MultiByteToWideChar(CP_ACP, 0, lpszStr, -1, NULL, NULL);
if (0 == nLen)
return NULL;
lpUnicode = new wchar_t[nLen + 1];
if (NULL == lpUnicode)
return NULL;
memset(lpUnicode, 0, sizeof(wchar_t) * (nLen + 1));
nLen = ::MultiByteToWideChar(CP_ACP, 0, lpszStr, -1, lpUnicode, nLen);
if (0 == nLen)
{
delete[]lpUnicode;
return NULL;
}
nLen = ::WideCharToMultiByte(CP_UTF8, 0, lpUnicode, -1, NULL, 0, NULL, NULL);
if (0 == nLen)
{
delete[]lpUnicode;
return NULL;
}
lpUtf8 = new char[nLen + 1];
if (NULL == lpUtf8)
{
delete[]lpUnicode;
return NULL;
}
memset(lpUtf8, 0, nLen + 1);
nLen = ::WideCharToMultiByte(CP_UTF8, 0, lpUnicode, -1, lpUtf8, nLen, NULL, NULL);
if (0 == nLen)
{
delete[]lpUnicode;
delete[]lpUtf8;
return NULL;
}
delete[]lpUnicode;
return lpUtf8;
}
char* EncodeUtil::Utf8ToAnsi(const char* lpszStr)
{
wchar_t* lpUnicode;
char* lpAnsi;
int nLen;
if (NULL == lpszStr)
return NULL;
nLen = ::MultiByteToWideChar(CP_UTF8, 0, lpszStr, -1, NULL, NULL);
if (0 == nLen)
return NULL;
lpUnicode = new wchar_t[nLen + 1];
if (NULL == lpUnicode)
return NULL;
memset(lpUnicode, 0, sizeof(wchar_t) * (nLen + 1));
nLen = ::MultiByteToWideChar(CP_UTF8, 0, lpszStr, -1, lpUnicode, nLen);
if (0 == nLen)
{
delete[]lpUnicode;
return NULL;
}
nLen = ::WideCharToMultiByte(CP_ACP, 0, lpUnicode, -1, NULL, 0, NULL, NULL);
if (0 == nLen)
{
delete[]lpUnicode;
return NULL;
}
lpAnsi = new char[nLen + 1];
if (NULL == lpAnsi)
{
delete[]lpUnicode;
return NULL;
}
memset(lpAnsi, 0, nLen + 1);
nLen = ::WideCharToMultiByte(CP_ACP, 0, lpUnicode, -1, lpAnsi, nLen, NULL, NULL);
if (0 == nLen)
{
delete[]lpUnicode;
delete[]lpAnsi;
return NULL;
}
delete[]lpUnicode;
return lpAnsi;
}
char* EncodeUtil::UnicodeToUtf8(const wchar_t* lpszStr)
{
char* lpUtf8;
int nLen;
if (NULL == lpszStr)
return NULL;
nLen = ::WideCharToMultiByte(CP_UTF8, 0, lpszStr, -1, NULL, 0, NULL, NULL);
if (0 == nLen)
return NULL;
lpUtf8 = new char[nLen + 1];
if (NULL == lpUtf8)
return NULL;
memset(lpUtf8, 0, nLen + 1);
nLen = ::WideCharToMultiByte(CP_UTF8, 0, lpszStr, -1, lpUtf8, nLen, NULL, NULL);
if (0 == nLen)
{
delete[]lpUtf8;
return NULL;
}
return lpUtf8;
}
wchar_t* EncodeUtil::Utf8ToUnicode(const char* lpszStr)
{
wchar_t* lpUnicode;
int nLen;
if (NULL == lpszStr)
return NULL;
nLen = ::MultiByteToWideChar(CP_UTF8, 0, lpszStr, -1, NULL, 0);
if (0 == nLen)
return NULL;
lpUnicode = new wchar_t[nLen + 1];
if (NULL == lpUnicode)
return NULL;
memset(lpUnicode, 0, sizeof(wchar_t) * (nLen + 1));
nLen = ::MultiByteToWideChar(CP_UTF8, 0, lpszStr, -1, lpUnicode, nLen);
if (0 == nLen)
{
delete[]lpUnicode;
return NULL;
}
return lpUnicode;
}
bool EncodeUtil::AnsiToUnicode(const char* lpszAnsi, wchar_t* lpszUnicode, int nLen)
{
int nRet = ::MultiByteToWideChar(CP_ACP, 0, lpszAnsi, -1, lpszUnicode, nLen);
return (0 == nRet) ? FALSE : TRUE;
}
bool EncodeUtil::UnicodeToAnsi(const wchar_t* lpszUnicode, char* lpszAnsi, int nLen)
{
int nRet = ::WideCharToMultiByte(CP_ACP, 0, lpszUnicode, -1, lpszAnsi, nLen, NULL, NULL);
return (0 == nRet) ? FALSE : TRUE;
}
bool EncodeUtil::AnsiToUtf8(const char* lpszAnsi, char* lpszUtf8, int nLen)
{
wchar_t* lpszUnicode = EncodeUtil::AnsiToUnicode(lpszAnsi);
if (NULL == lpszUnicode)
return FALSE;
int nRet = EncodeUtil::UnicodeToUtf8(lpszUnicode, lpszUtf8, nLen);
delete[]lpszUnicode;
return (0 == nRet) ? FALSE : TRUE;
}
bool EncodeUtil::Utf8ToAnsi(const char* lpszUtf8, char* lpszAnsi, int nLen)
{
wchar_t* lpszUnicode = EncodeUtil::Utf8ToUnicode(lpszUtf8);
if (NULL == lpszUnicode)
return FALSE;
int nRet = UnicodeToAnsi(lpszUnicode, lpszAnsi, nLen);
delete[]lpszUnicode;
return (0 == nRet) ? FALSE : TRUE;
}
bool EncodeUtil::UnicodeToUtf8(const wchar_t* lpszUnicode, char* lpszUtf8, int nLen)
{
int nRet = ::WideCharToMultiByte(CP_UTF8, 0, lpszUnicode, -1, lpszUtf8, nLen, NULL, NULL);
return (0 == nRet) ? FALSE : TRUE;
}
bool EncodeUtil::Utf8ToUnicode(const char* lpszUtf8, wchar_t* lpszUnicode, int nLen)
{
int nRet = ::MultiByteToWideChar(CP_UTF8, 0, lpszUtf8, -1, lpszUnicode, nLen);
return (0 == nRet) ? FALSE : TRUE;
}
std::wstring EncodeUtil::AnsiToUnicode(const std::string& strAnsi)
{
std::wstring strUnicode;
wchar_t* lpszUnicode = EncodeUtil::AnsiToUnicode(strAnsi.c_str());
if (lpszUnicode != NULL)
{
strUnicode = lpszUnicode;
delete[]lpszUnicode;
}
return strUnicode;
}
std::string EncodeUtil::UnicodeToAnsi(const std::wstring& strUnicode)
{
std::string strAnsi;
char* lpszAnsi = UnicodeToAnsi(strUnicode.c_str());
if (lpszAnsi != NULL)
{
strAnsi = lpszAnsi;
delete[]lpszAnsi;
}
return strAnsi;
}
std::string EncodeUtil::AnsiToUtf8(const std::string& strAnsi)
{
std::string strUtf8;
char* lpszUtf8 = AnsiToUtf8(strAnsi.c_str());
if (lpszUtf8 != NULL)
{
strUtf8 = lpszUtf8;
delete[]lpszUtf8;
}
return strUtf8;
}
std::string EncodeUtil::Utf8ToAnsi(const std::string& strUtf8)
{
std::string strAnsi;
char* lpszAnsi = Utf8ToAnsi(strUtf8.c_str());
if (lpszAnsi != NULL)
{
strAnsi = lpszAnsi;
delete[]lpszAnsi;
}
return strAnsi;
}
std::string EncodeUtil::UnicodeToUtf8(const std::wstring& strUnicode)
{
std::string strUtf8;
char* lpszUtf8 = EncodeUtil::UnicodeToUtf8(strUnicode.c_str());
if (lpszUtf8 != NULL)
{
strUtf8 = lpszUtf8;
delete[]lpszUtf8;
}
return strUtf8;
}
std::wstring EncodeUtil::Utf8ToUnicode(const std::string& strUtf8)
{
std::wstring strUnicode;
wchar_t* lpszUnicode = EncodeUtil::Utf8ToUnicode(strUtf8.c_str());
if (lpszUnicode != NULL)
{
strUnicode = lpszUnicode;
delete[]lpszUnicode;
}
return strUnicode;
}
void EncodeUtil::DecodeQuotedPrintable(const char* pSrc, char* pDest)
{
long LEN = strlen(pSrc);
int step = 0;
char temp[3];
long before = 0;
long offset = 0;
do
{
if (pSrc[offset] != '=')
{
offset++;
continue;
}
memcpy(pDest + step, pSrc + before, offset - before);
step += offset - before;
before = offset + 1;
offset++;
if ((pSrc[offset] == 0x0D) || (pSrc[offset] == 0x0A))
{
before = offset + 1;
offset++;
if ((pSrc[offset] == 0x0D) || (pSrc[offset] == 0x0A))
{
before = offset + 1;
offset++;
}
continue;
}
temp[0] = pSrc[offset];
temp[0] = temp[0] < 0x41 ? temp[0] - 0x30 : (temp[0] < 0x61 ? temp[0] - 0x37 : temp[0] - 0x57);
offset++;
temp[1] = pSrc[offset];
temp[1] = temp[1] < 0x41 ? temp[1] - 0x30 : (temp[1] < 0x61 ? temp[1] - 0x37 : temp[1] - 0x57);
temp[2] = (temp[0] << 4) | (temp[1] & 0x0F);
memcpy(pDest + step, temp + 2, 1);
step += 1;
before = offset + 1;
offset++;
} while (offset < LEN);
if (before < LEN)
{
memcpy(pDest + step, pSrc + before, LEN - before);
step += LEN - before;
}
pDest[step] = 0x00;
}
bool EncodeUtil::UTF8ToUnicode(const char* pszUTF8, std::wstring& strDest)
{
strDest.clear();
long lLen = ::MultiByteToWideChar(CP_UTF8, 0, pszUTF8, -1, NULL, 0);
if (lLen <= 0)
return false;
wchar_t* pDest = new wchar_t[lLen + 10];
memset(pDest, 0, sizeof(wchar_t) * (lLen + 10));
long lnWide = ::MultiByteToWideChar(CP_UTF8, 0, pszUTF8, -1, pDest, lLen);
pDest[lLen - 1] = 0;
strDest.append(pDest);
return true;
}
bool EncodeUtil::GB2312ToUnicode(const char* pszGB2312, std::wstring& strDest)
{
strDest.clear();
long lLen = ::MultiByteToWideChar(936, 0, pszGB2312, -1, NULL, 0);
if (lLen <= 0)
return false;
wchar_t* pDest = new wchar_t[lLen + 10];
memset(pDest, 0, sizeof(wchar_t) * (lLen + 10));
long lnWide = ::MultiByteToWideChar(936, 0, pszGB2312, -1, pDest, lLen);
pDest[lLen - 1] = 0;
strDest.append(pDest);
return true;
}
bool EncodeUtil::UnicodeToGB2312(const wchar_t* pszUnicode, std::string& strDest)
{
strDest.clear();
long lLen = ::WideCharToMultiByte(936, 0, pszUnicode, -1, NULL, 0, NULL, NULL);
if (lLen <= 0)
return false;
char* pDest = new char[lLen + 10];
memset(pDest, 0, sizeof(char) * lLen + 10);
long lCovertLen = ::WideCharToMultiByte(936, 0, pszUnicode, -1, pDest, lLen, NULL, NULL);
pDest[lLen - 1] = 0;
strDest.append(pDest);
return true;
}
std::string EncodeUtil::ws2s(const std::wstring& ws)
{
size_t i;
std::string curLocale = setlocale(LC_ALL, NULL);
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, 0x0, _dsize);
wcstombs_s(&i, _dest, _dsize, _source, _dsize);
std::string result = _dest;
delete[] _dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
std::wstring EncodeUtil::s2ws(const std::string& s)
{
size_t i;
std::string curLocale = setlocale(LC_ALL, NULL);
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, 0x0, _dsize);
mbstowcs_s(&i, _dest, _dsize, _source, _dsize);
std::wstring result = _dest;
delete[] _dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
//int EncodeUtil::code_convert(char* from_charset, char* to_charset, char* inbuf, size_t inlen, char* outbuf, size_t& outlen)
//{
// iconv_t cd;
// char** pin = &inbuf;
// char** pout = &outbuf;
//
// cd = iconv_open(to_charset, from_charset);
// if (cd == 0)
// return false;
//
// memset(outbuf, 0, outlen);
//
// if (iconv(cd, pin, &inlen, pout, &outlen) == -1)
// return false;
//
// iconv_close(cd);
// return true;
//}
//
//bool EncodeUtil::Utf8ToGbk(char *inbuf, size_t inlen, char *outbuf, size_t outlen)
//{
// return code_convert("utf-8", "gbk", inbuf, inlen, outbuf, outlen);
//}
//
//bool EncodeUtil::GbkToUtf8(char* inbuf, size_t inlen, char* outbuf, size_t outlen)
//{
// return code_convert("gbk", "utf-8", inbuf, inlen, outbuf, outlen);
//}
//
//bool EncodeUtil::Utf8ToGbk2(char* inbuf, size_t inlen, char* outbuf, size_t& outlen)
//{
// return code_convert("gbk", "utf-8", inbuf, inlen, outbuf, outlen);
//}
//
//int EncodeUtil::GbkToUtf8(char* utfstr, const char* srcstr, int maxutfstrlen)
//{
// if (NULL == srcstr)
// return -1;
//
// //首先先将gbk编码转换为unicode编码
// if (NULL == setlocale(LC_ALL, "zh_CN.gbk"))//设置转换为unicode前的码,当前为gbk编码
// return -1;
//
// int unicodelen = mbstowcs(NULL, srcstr, 0);//计算转换后的长度
// if (unicodelen <= 0)
// return -1;
//
// wchar_t* unicodestr = (wchar_t *)calloc(sizeof(wchar_t), unicodelen + 1);
// mbstowcs(unicodestr, srcstr, strlen(srcstr));//将gbk转换为unicode
//
// //将unicode编码转换为utf8编码
// if (NULL == setlocale(LC_ALL, "zh_CN.utf8"))//设置unicode转换后的码,当前为utf8
// return -1;
//
// int utflen = wcstombs(NULL, unicodestr, 0);//计算转换后的长度
// if (utflen <= 0)
// return -1;
// else if (utflen >= maxutfstrlen)//判断空间是否足够
// return -1;
//
// wcstombs(utfstr, unicodestr, utflen);
// utfstr[utflen] = 0;//添加结束符
// free(unicodestr);
//
// return utflen;
//}
五、Base64Util编解码
//Base64Util.h
#pragma once
#include <string>
class Base64Util final
{
private:
Base64Util() = delete;
~Base64Util() = delete;
Base64Util(const Base64Util& rhs) = delete;
Base64Util& operator=(const Base64Util& rhs) = delete;
public:
static int encode(char* pDest, const char* pSource, int lenSource, char chMask, int maxDest);
static int decode(char* pDest, const char* pSource, int lenSource, char chMask, int maxDest);
static void decode(const char* pData, int nDataByte, std::string& strDecode);
static bool check(char* lpString);
};
//Base64Util.cpp
#include "Base64Util.h"
/////////////////////////////////////////////////////////////////////////////////////////////////
//解码表
static const char DECODE_TABLE[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62, // '+'
0, 0, 0,
63, // '/'
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
0, 0, 0, 0, 0, 0,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
};
static const char ENCODE_TABLE[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" };
int Base64Util::encode(char* pDest, const char* pSource, int lenSource, char chMask, int maxDest)
{
char c1, c2, c3;
int i = 0, lenDest(0), lDiv(lenSource / 3), lMod(lenSource % 3);
for (; i < lDiv; ++i, lenDest += 4)
{
if (lenDest + 4 >= maxDest)
return 0;
c1 = *pSource++;
c2 = *pSource++;
c3 = *pSource++;
*pDest++ = ENCODE_TABLE[c1 >> 2];
*pDest++ = ENCODE_TABLE[((c1 << 4) | (c2 >> 4)) & 0X3F];
*pDest++ = ENCODE_TABLE[((c2 << 2) | (c3 >> 6)) & 0X3F];
*pDest++ = ENCODE_TABLE[c3 & 0X3F];
}
if (lMod == 1)
{
if (lenDest + 4 >= maxDest) return(0);
c1 = *pSource++;
*pDest++ = ENCODE_TABLE[(c1 & 0XFC) >> 2];
*pDest++ = ENCODE_TABLE[((c1 & 0X03) << 4)];
*pDest++ = chMask;
*pDest++ = chMask;
lenDest += 4;
}
else if (lMod == 2)
{
if (lenDest + 4 >= maxDest) return(0);
c1 = *pSource++;
c2 = *pSource++;
*pDest++ = ENCODE_TABLE[(c1 & 0XFC) >> 2];
*pDest++ = ENCODE_TABLE[((c1 & 0X03) << 4) | ((c2 & 0XF0) >> 4)];
*pDest++ = ENCODE_TABLE[((c2 & 0X0F) << 2)];
*pDest++ = chMask;
lenDest += 4;
}
*pDest = 0;
return lenDest;
}
int Base64Util::decode(char* pDest, const char* pSource, int lenSource, char chMask, int maxDest)
{
int lenDest = 0, nValue = 0, i = 0;
for (; i < lenSource; i += 4)
{
nValue = DECODE_TABLE[(int)(*pSource)] << 18;
pSource++;
nValue += DECODE_TABLE[(int)*pSource] << 12;
pSource++;
if (++lenDest >= maxDest)
break;
*pDest++ = char((nValue & 0X00FF0000) >> 16);
if (*pSource != chMask)
{
nValue += DECODE_TABLE[(int)*pSource] << 6;
pSource++;
if (++lenDest >= maxDest)
break;
*pDest++ = (nValue & 0X0000FF00) >> 8;
if (*pSource != chMask)
{
nValue += DECODE_TABLE[(int)*pSource];
pSource++;
if (++lenDest >= maxDest)
break;
*pDest++ = nValue & 0X000000FF;
}
}
}
*pDest = 0;
return lenDest;
}
void Base64Util::decode(const char* pData, int nDataByte, std::string& strDecode)
{
strDecode.clear();
int nValue = 0, i = 0, OutByte = 0;
while (i < nDataByte)
{
if (*pData != '\r' && *pData != '\n')
{
nValue = DECODE_TABLE[*pData++] << 18;
nValue += DECODE_TABLE[*pData++] << 12;
strDecode += (char)((nValue & 0x00FF0000) >> 16);
OutByte++;
if (*pData != '=')
{
nValue += DECODE_TABLE[*pData++] << 6;
strDecode += (char)((nValue & 0x0000FF00) >> 8);
OutByte++;
if (*pData != '=')
{
nValue += DECODE_TABLE[*pData++];
strDecode += (char)(nValue & 0x000000FF);
OutByte++;
}
}
i += 4;
}
else // 回车换行,跳过
{
pData++;
i++;
}
}
}
bool Base64Util::check(char* lpString)
{
for (; *lpString; ++lpString)
{
switch (*lpString)
{
case '+': *lpString = '@'; break;
case '@': *lpString = '+'; break;
case '=': *lpString = '$'; break;
case '$': *lpString = '='; break;
case '/': *lpString = '#'; break;
case '#': *lpString = '/'; break;
default:
if (*lpString >= 'A' && *lpString <= 'Z')
*lpString = *lpString - 'A' + 'a';
else if (*lpString >= 'a' && *lpString <= 'z')
*lpString = *lpString - 'a' + 'A';
else if (*lpString >= '0' && *lpString <= '4')
*lpString = *lpString - '0' + '5';
else if (*lpString >= '5' && *lpString <= '9')
*lpString = *lpString - '5' + '0';
else
return false;
}
}
return true;
}
六、char字符与十六进制字符互转
//转换
char hb2hex(unsigned char hb) {
hb = hb & 0xF;
return hb < 10 ? '0' + hb : hb - 10 + 'A';
}
unsigned char hex2hb(unsigned char hb) {
if(hb >= 'A' && hb <= 'F')
{
return (hb - 'A' + 10);
}
else if(hb >= 'a' && hb <= 'f')
{
return (hb - 'a' + 10);
}
else
{
return (hb - '0');
}
}
七、StringPiece.h
背景
- 很多时候,当传入一个字符串到函数时,往往只是读取字符串时
- 若使用std::string,当实参为const char 时,会*分配内存并拷贝该字符串以生成一个std::string
- 当一个函数接受一个const std::string,而在该函数内部,又需要传递该值到另一个函数,则又需要重新生成一个std::string
目的
- 当某个接口参数是接受字符串类型时,为了减少不必要的开销
- 该类型可以接受const char *,std::string,减少冗余代码编写
要点
- StringPiece(google), StringRef(llvm), string_ref(boost),本质名,non-owning reference to a string
- 通过隐式转换,方便地从const char*, std::string转换到此类型
- 该类通过保存字符串指针和长度,来避免不必要的复制
- 只支持非修改操作
- 开销很低,只需要sizeof(const char*) + sizeof(size_t)字节
- 支持所有的类容器操作
- 因为StringPiece不拥有数据,所以确保在StringPiece生命期内,该数据可用 ```cpp // Taken from PCRE pcre_stringpiece.h // // Copyright (c) 2005, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Author: Sanjay Ghemawat // // A string like object that points into another piece of memory. // Useful for providing an interface that allows clients to easily // pass in either a “const char“ or a “string”. // // Arghh! I wish C++ literals were automatically of type “string”.
ifndef MUDUO_BASE_STRINGPIECE_H
define MUDUO_BASE_STRINGPIECE_H
include
include // for ostream forward-declaration
include “muduo/base/Types.h”
namespace muduo {
// For passing C-style string argument to a function. class StringArg // copyable { public: StringArg(const char* str) : str_(str) { }
StringArg(const string& str) : str_(str.c_str()) { }
const char* cstr() const { return str; }
private: const char* str_; };
class StringPiece { private: const char* ptr; int length;
public:
// We provide non-explicit singleton constructors so users can pass
// in a “const char“ or a “string” wherever a “StringPiece” is
// expected.
StringPiece()
: ptr(NULL), length(0) { }
StringPiece(const char str)
: ptr(str), length(staticcast
// data() may return a pointer to a buffer with embedded NULs, and the // returned buffer may or may not be null terminated. Therefore it is // typically a mistake to pass data() to a routine that expects a NUL // terminated string. Use “asstring().c_str()” if you really need to do // this. Or better yet, change your routine so it does not rely on NUL // termination. const char* data() const { return ptr; } int size() const { return length; } bool empty() const { return length == 0; } const char begin() const { return ptr_; } const char end() const { return ptr + length; }
void clear() { ptr = NULL; length = 0; }
void set(const char buffer, int len) { ptr = buffer; length = len; }
void set(const char str) {
ptr = str;
length = staticcast
char operator const { return ptr_[i]; }
void removeprefix(int n) { ptr += n; length_ -= n; }
void removesuffix(int n) { length -= n; }
bool operator==(const StringPiece& x) const { return ((length == x.length) && (memcmp(ptr, x.ptr, length_) == 0)); } bool operator!=(const StringPiece& x) const { return !(*this == x); }
//通过宏定义,实现了StringPiece类<,<=,>,>=的比较,当然本质还是比较ptr指向的字符串。宏定义中cmp就是我们想要进行操作的字符串,aux用于辅助比较。举例来说,如果我们有StringPiece str1(“abcz”),str2(“abcdef”), //std::cout << (str1 < str2) << std:: endl的结果如何呢?由于str1的length小于str2的length,那么r = 0;return后的语句里 r < 0不成立,r==0成立但二者length不相等,所以返回false。其他操作也可如此类推,总之这一段代码技巧性很强。
define STRINGPIECE_BINARY_PREDICATE(cmp,auxcmp) \
bool operator cmp (const StringPiece& x) const { \ int r = memcmp(ptr, x.ptr, length < x.length ? length : x.length); \ return ((r auxcmp 0) || ((r == 0) && (length cmp x.length))); \ } STRINGPIECE_BINARY_PREDICATE(<, <); STRINGPIECE_BINARY_PREDICATE(<=, <); STRINGPIECE_BINARY_PREDICATE(>=, >); STRINGPIECE_BINARY_PREDICATE(>, >);
undef STRINGPIECE_BINARY_PREDICATE
int compare(const StringPiece& x) const { int r = memcmp(ptr, x.ptr, length < x.length ? length : x.length); if (r == 0) { if (length < x.length) r = -1; else if (length > x.length) r = +1; } return r; }
string as_string() const { return string(data(), size()); }
void CopyToString(string* target) const { target->assign(ptr, length); }
// Does “this” start with “x” bool startswith(const StringPiece& x) const { return ((length >= x.length) && (memcmp(ptr, x.ptr, x.length) == 0)); } };
} // namespace muduo
// ————————————————————————————————— // Functions used to create STL containers that use StringPiece // Remember that a StringPiece’s lifetime had better be less than // that of the underlying string or char*. If it is not, then you // cannot safely store a StringPiece into an STL container // —————————————————————————————————
ifdef HAVE_TYPE_TRAITS
// This makes vector
endif
// allow StringPiece to be logged std::ostream& operator<<(std::ostream& o, const muduo::StringPiece& piece);
endif // MUDUO_BASE_STRINGPIECE_H
string_view.h
```cpp
//
// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// -----------------------------------------------------------------------------
// File: string_view.h
// -----------------------------------------------------------------------------
//
// This file contains the definition of the `absl::string_view` class. A
// `string_view` points to a contiguous span of characters, often part or all of
// another `std::string`, double-quoted string literal, character array, or even
// another `string_view`.
//
// This `absl::string_view` abstraction is designed to be a drop-in
// replacement for the C++17 `std::string_view` abstraction.
#ifndef ABSL_STRINGS_STRING_VIEW_H_
#define ABSL_STRINGS_STRING_VIEW_H_
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstring>
#include <iosfwd>
#include <iterator>
#include <limits>
#include <string>
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/base/macros.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
#ifdef ABSL_USES_STD_STRING_VIEW
#include <string_view> // IWYU pragma: export
namespace absl {
ABSL_NAMESPACE_BEGIN
using string_view = std::string_view;
ABSL_NAMESPACE_END
} // namespace absl
#else // ABSL_USES_STD_STRING_VIEW
#if ABSL_HAVE_BUILTIN(__builtin_memcmp) || \
(defined(__GNUC__) && !defined(__clang__))
#define ABSL_INTERNAL_STRING_VIEW_MEMCMP __builtin_memcmp
#else // ABSL_HAVE_BUILTIN(__builtin_memcmp)
#define ABSL_INTERNAL_STRING_VIEW_MEMCMP memcmp
#endif // ABSL_HAVE_BUILTIN(__builtin_memcmp)
#if defined(__cplusplus) && __cplusplus >= 201402L
#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR constexpr
#else
#define ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR
#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
// absl::string_view
//
// A `string_view` provides a lightweight view into the string data provided by
// a `std::string`, double-quoted string literal, character array, or even
// another `string_view`. A `string_view` does *not* own the string to which it
// points, and that data cannot be modified through the view.
//
// You can use `string_view` as a function or method parameter anywhere a
// parameter can receive a double-quoted string literal, `const char*`,
// `std::string`, or another `absl::string_view` argument with no need to copy
// the string data. Systematic use of `string_view` within function arguments
// reduces data copies and `strlen()` calls.
//
// Because of its small size, prefer passing `string_view` by value:
//
// void MyFunction(absl::string_view arg);
//
// If circumstances require, you may also pass one by const reference:
//
// void MyFunction(const absl::string_view& arg); // not preferred
//
// Passing by value generates slightly smaller code for many architectures.
//
// In either case, the source data of the `string_view` must outlive the
// `string_view` itself.
//
// A `string_view` is also suitable for local variables if you know that the
// lifetime of the underlying object is longer than the lifetime of your
// `string_view` variable. However, beware of binding a `string_view` to a
// temporary value:
//
// // BAD use of string_view: lifetime problem
// absl::string_view sv = obj.ReturnAString();
//
// // GOOD use of string_view: str outlives sv
// std::string str = obj.ReturnAString();
// absl::string_view sv = str;
//
// Due to lifetime issues, a `string_view` is sometimes a poor choice for a
// return value and usually a poor choice for a data member. If you do use a
// `string_view` this way, it is your responsibility to ensure that the object
// pointed to by the `string_view` outlives the `string_view`.
//
// A `string_view` may represent a whole string or just part of a string. For
// example, when splitting a string, `std::vector<absl::string_view>` is a
// natural data type for the output.
//
// For another example, a Cord is a non-contiguous, potentially very
// long string-like object. The Cord class has an interface that iteratively
// provides string_view objects that point to the successive pieces of a Cord
// object.
//
// When constructed from a source which is NUL-terminated, the `string_view`
// itself will not include the NUL-terminator unless a specific size (including
// the NUL) is passed to the constructor. As a result, common idioms that work
// on NUL-terminated strings do not work on `string_view` objects. If you write
// code that scans a `string_view`, you must check its length rather than test
// for nul, for example. Note, however, that nuls may still be embedded within
// a `string_view` explicitly.
//
// You may create a null `string_view` in two ways:
//
// absl::string_view sv;
// absl::string_view sv(nullptr, 0);
//
// For the above, `sv.data() == nullptr`, `sv.length() == 0`, and
// `sv.empty() == true`. Also, if you create a `string_view` with a non-null
// pointer then `sv.data() != nullptr`. Thus, you can use `string_view()` to
// signal an undefined value that is different from other `string_view` values
// in a similar fashion to how `const char* p1 = nullptr;` is different from
// `const char* p2 = "";`. However, in practice, it is not recommended to rely
// on this behavior.
//
// Be careful not to confuse a null `string_view` with an empty one. A null
// `string_view` is an empty `string_view`, but some empty `string_view`s are
// not null. Prefer checking for emptiness over checking for null.
//
// There are many ways to create an empty string_view:
//
// const char* nullcp = nullptr;
// // string_view.size() will return 0 in all cases.
// absl::string_view();
// absl::string_view(nullcp, 0);
// absl::string_view("");
// absl::string_view("", 0);
// absl::string_view("abcdef", 0);
// absl::string_view("abcdef" + 6, 0);
//
// All empty `string_view` objects whether null or not, are equal:
//
// absl::string_view() == absl::string_view("", 0)
// absl::string_view(nullptr, 0) == absl::string_view("abcdef"+6, 0)
class string_view {
public:
using traits_type = std::char_traits<char>;
using value_type = char;
using pointer = char*;
using const_pointer = const char*;
using reference = char&;
using const_reference = const char&;
using const_iterator = const char*;
using iterator = const_iterator;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;
using size_type = size_t;
using difference_type = std::ptrdiff_t;
static constexpr size_type npos = static_cast<size_type>(-1);
// Null `string_view` constructor
constexpr string_view() noexcept : ptr_(nullptr), length_(0) {}
// Implicit constructors
template <typename Allocator>
string_view( // NOLINT(runtime/explicit)
const std::basic_string<char, std::char_traits<char>, Allocator>& str
ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
// This is implemented in terms of `string_view(p, n)` so `str.size()`
// doesn't need to be reevaluated after `ptr_` is set.
// The length check is also skipped since it is unnecessary and causes
// code bloat.
: string_view(str.data(), str.size(), SkipCheckLengthTag{}) {}
// Implicit constructor of a `string_view` from NUL-terminated `str`. When
// accepting possibly null strings, use `absl::NullSafeStringView(str)`
// instead (see below).
// The length check is skipped since it is unnecessary and causes code bloat.
constexpr string_view(const char* str) // NOLINT(runtime/explicit)
: ptr_(str), length_(str ? StrlenInternal(str) : 0) {}
// Implicit constructor of a `string_view` from a `const char*` and length.
constexpr string_view(const char* data, size_type len)
: ptr_(data), length_(CheckLengthInternal(len)) {}
// NOTE: Harmlessly omitted to work around gdb bug.
// constexpr string_view(const string_view&) noexcept = default;
// string_view& operator=(const string_view&) noexcept = default;
// Iterators
// string_view::begin()
//
// Returns an iterator pointing to the first character at the beginning of the
// `string_view`, or `end()` if the `string_view` is empty.
constexpr const_iterator begin() const noexcept { return ptr_; }
// string_view::end()
//
// Returns an iterator pointing just beyond the last character at the end of
// the `string_view`. This iterator acts as a placeholder; attempting to
// access it results in undefined behavior.
constexpr const_iterator end() const noexcept { return ptr_ + length_; }
// string_view::cbegin()
//
// Returns a const iterator pointing to the first character at the beginning
// of the `string_view`, or `end()` if the `string_view` is empty.
constexpr const_iterator cbegin() const noexcept { return begin(); }
// string_view::cend()
//
// Returns a const iterator pointing just beyond the last character at the end
// of the `string_view`. This pointer acts as a placeholder; attempting to
// access its element results in undefined behavior.
constexpr const_iterator cend() const noexcept { return end(); }
// string_view::rbegin()
//
// Returns a reverse iterator pointing to the last character at the end of the
// `string_view`, or `rend()` if the `string_view` is empty.
const_reverse_iterator rbegin() const noexcept {
return const_reverse_iterator(end());
}
// string_view::rend()
//
// Returns a reverse iterator pointing just before the first character at the
// beginning of the `string_view`. This pointer acts as a placeholder;
// attempting to access its element results in undefined behavior.
const_reverse_iterator rend() const noexcept {
return const_reverse_iterator(begin());
}
// string_view::crbegin()
//
// Returns a const reverse iterator pointing to the last character at the end
// of the `string_view`, or `crend()` if the `string_view` is empty.
const_reverse_iterator crbegin() const noexcept { return rbegin(); }
// string_view::crend()
//
// Returns a const reverse iterator pointing just before the first character
// at the beginning of the `string_view`. This pointer acts as a placeholder;
// attempting to access its element results in undefined behavior.
const_reverse_iterator crend() const noexcept { return rend(); }
// Capacity Utilities
// string_view::size()
//
// Returns the number of characters in the `string_view`.
constexpr size_type size() const noexcept { return length_; }
// string_view::length()
//
// Returns the number of characters in the `string_view`. Alias for `size()`.
constexpr size_type length() const noexcept { return size(); }
// string_view::max_size()
//
// Returns the maximum number of characters the `string_view` can hold.
constexpr size_type max_size() const noexcept { return kMaxSize; }
// string_view::empty()
//
// Checks if the `string_view` is empty (refers to no characters).
constexpr bool empty() const noexcept { return length_ == 0; }
// string_view::operator[]
//
// Returns the ith element of the `string_view` using the array operator.
// Note that this operator does not perform any bounds checking.
constexpr const_reference operator[](size_type i) const {
return ABSL_HARDENING_ASSERT(i < size()), ptr_[i];
}
// string_view::at()
//
// Returns the ith element of the `string_view`. Bounds checking is performed,
// and an exception of type `std::out_of_range` will be thrown on invalid
// access.
constexpr const_reference at(size_type i) const {
return ABSL_PREDICT_TRUE(i < size())
? ptr_[i]
: ((void)base_internal::ThrowStdOutOfRange(
"absl::string_view::at"),
ptr_[i]);
}
// string_view::front()
//
// Returns the first element of a `string_view`.
constexpr const_reference front() const {
return ABSL_HARDENING_ASSERT(!empty()), ptr_[0];
}
// string_view::back()
//
// Returns the last element of a `string_view`.
constexpr const_reference back() const {
return ABSL_HARDENING_ASSERT(!empty()), ptr_[size() - 1];
}
// string_view::data()
//
// Returns a pointer to the underlying character array (which is of course
// stored elsewhere). Note that `string_view::data()` may contain embedded nul
// characters, but the returned buffer may or may not be NUL-terminated;
// therefore, do not pass `data()` to a routine that expects a NUL-terminated
// string.
constexpr const_pointer data() const noexcept { return ptr_; }
// Modifiers
// string_view::remove_prefix()
//
// Removes the first `n` characters from the `string_view`. Note that the
// underlying string is not changed, only the view.
ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_prefix(size_type n) {
ABSL_HARDENING_ASSERT(n <= length_);
ptr_ += n;
length_ -= n;
}
// string_view::remove_suffix()
//
// Removes the last `n` characters from the `string_view`. Note that the
// underlying string is not changed, only the view.
ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void remove_suffix(size_type n) {
ABSL_HARDENING_ASSERT(n <= length_);
length_ -= n;
}
// string_view::swap()
//
// Swaps this `string_view` with another `string_view`.
ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR void swap(string_view& s) noexcept {
auto t = *this;
*this = s;
s = t;
}
// Explicit conversion operators
// Converts to `std::basic_string`.
template <typename A>
explicit operator std::basic_string<char, traits_type, A>() const {
if (!data()) return {};
return std::basic_string<char, traits_type, A>(data(), size());
}
// string_view::copy()
//
// Copies the contents of the `string_view` at offset `pos` and length `n`
// into `buf`.
size_type copy(char* buf, size_type n, size_type pos = 0) const {
if (ABSL_PREDICT_FALSE(pos > length_)) {
base_internal::ThrowStdOutOfRange("absl::string_view::copy");
}
size_type rlen = (std::min)(length_ - pos, n);
if (rlen > 0) {
const char* start = ptr_ + pos;
traits_type::copy(buf, start, rlen);
}
return rlen;
}
// string_view::substr()
//
// Returns a "substring" of the `string_view` (at offset `pos` and length
// `n`) as another string_view. This function throws `std::out_of_bounds` if
// `pos > size`.
// Use absl::ClippedSubstr if you need a truncating substr operation.
constexpr string_view substr(size_type pos = 0, size_type n = npos) const {
return ABSL_PREDICT_FALSE(pos > length_)
? (base_internal::ThrowStdOutOfRange(
"absl::string_view::substr"),
string_view())
: string_view(ptr_ + pos, Min(n, length_ - pos));
}
// string_view::compare()
//
// Performs a lexicographical comparison between this `string_view` and
// another `string_view` `x`, returning a negative value if `*this` is less
// than `x`, 0 if `*this` is equal to `x`, and a positive value if `*this`
// is greater than `x`.
constexpr int compare(string_view x) const noexcept {
return CompareImpl(length_, x.length_,
Min(length_, x.length_) == 0
? 0
: ABSL_INTERNAL_STRING_VIEW_MEMCMP(
ptr_, x.ptr_, Min(length_, x.length_)));
}
// Overload of `string_view::compare()` for comparing a substring of the
// 'string_view` and another `absl::string_view`.
constexpr int compare(size_type pos1, size_type count1, string_view v) const {
return substr(pos1, count1).compare(v);
}
// Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a substring of another `absl::string_view`.
constexpr int compare(size_type pos1, size_type count1, string_view v,
size_type pos2, size_type count2) const {
return substr(pos1, count1).compare(v.substr(pos2, count2));
}
// Overload of `string_view::compare()` for comparing a `string_view` and a
// a different C-style string `s`.
constexpr int compare(const char* s) const { return compare(string_view(s)); }
// Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a different string C-style string `s`.
constexpr int compare(size_type pos1, size_type count1, const char* s) const {
return substr(pos1, count1).compare(string_view(s));
}
// Overload of `string_view::compare()` for comparing a substring of the
// `string_view` and a substring of a different C-style string `s`.
constexpr int compare(size_type pos1, size_type count1, const char* s,
size_type count2) const {
return substr(pos1, count1).compare(string_view(s, count2));
}
// Find Utilities
// string_view::find()
//
// Finds the first occurrence of the substring `s` within the `string_view`,
// returning the position of the first character's match, or `npos` if no
// match was found.
size_type find(string_view s, size_type pos = 0) const noexcept;
// Overload of `string_view::find()` for finding the given character `c`
// within the `string_view`.
size_type find(char c, size_type pos = 0) const noexcept;
// Overload of `string_view::find()` for finding a substring of a different
// C-style string `s` within the `string_view`.
size_type find(const char* s, size_type pos, size_type count) const {
return find(string_view(s, count), pos);
}
// Overload of `string_view::find()` for finding a different C-style string
// `s` within the `string_view`.
size_type find(const char* s, size_type pos = 0) const {
return find(string_view(s), pos);
}
// string_view::rfind()
//
// Finds the last occurrence of a substring `s` within the `string_view`,
// returning the position of the first character's match, or `npos` if no
// match was found.
size_type rfind(string_view s, size_type pos = npos) const noexcept;
// Overload of `string_view::rfind()` for finding the last given character `c`
// within the `string_view`.
size_type rfind(char c, size_type pos = npos) const noexcept;
// Overload of `string_view::rfind()` for finding a substring of a different
// C-style string `s` within the `string_view`.
size_type rfind(const char* s, size_type pos, size_type count) const {
return rfind(string_view(s, count), pos);
}
// Overload of `string_view::rfind()` for finding a different C-style string
// `s` within the `string_view`.
size_type rfind(const char* s, size_type pos = npos) const {
return rfind(string_view(s), pos);
}
// string_view::find_first_of()
//
// Finds the first occurrence of any of the characters in `s` within the
// `string_view`, returning the start position of the match, or `npos` if no
// match was found.
size_type find_first_of(string_view s, size_type pos = 0) const noexcept;
// Overload of `string_view::find_first_of()` for finding a character `c`
// within the `string_view`.
size_type find_first_of(char c, size_type pos = 0) const noexcept {
return find(c, pos);
}
// Overload of `string_view::find_first_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
size_type find_first_of(const char* s, size_type pos,
size_type count) const {
return find_first_of(string_view(s, count), pos);
}
// Overload of `string_view::find_first_of()` for finding a different C-style
// string `s` within the `string_view`.
size_type find_first_of(const char* s, size_type pos = 0) const {
return find_first_of(string_view(s), pos);
}
// string_view::find_last_of()
//
// Finds the last occurrence of any of the characters in `s` within the
// `string_view`, returning the start position of the match, or `npos` if no
// match was found.
size_type find_last_of(string_view s, size_type pos = npos) const noexcept;
// Overload of `string_view::find_last_of()` for finding a character `c`
// within the `string_view`.
size_type find_last_of(char c, size_type pos = npos) const noexcept {
return rfind(c, pos);
}
// Overload of `string_view::find_last_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
size_type find_last_of(const char* s, size_type pos, size_type count) const {
return find_last_of(string_view(s, count), pos);
}
// Overload of `string_view::find_last_of()` for finding a different C-style
// string `s` within the `string_view`.
size_type find_last_of(const char* s, size_type pos = npos) const {
return find_last_of(string_view(s), pos);
}
// string_view::find_first_not_of()
//
// Finds the first occurrence of any of the characters not in `s` within the
// `string_view`, returning the start position of the first non-match, or
// `npos` if no non-match was found.
size_type find_first_not_of(string_view s, size_type pos = 0) const noexcept;
// Overload of `string_view::find_first_not_of()` for finding a character
// that is not `c` within the `string_view`.
size_type find_first_not_of(char c, size_type pos = 0) const noexcept;
// Overload of `string_view::find_first_not_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
size_type find_first_not_of(const char* s, size_type pos,
size_type count) const {
return find_first_not_of(string_view(s, count), pos);
}
// Overload of `string_view::find_first_not_of()` for finding a different
// C-style string `s` within the `string_view`.
size_type find_first_not_of(const char* s, size_type pos = 0) const {
return find_first_not_of(string_view(s), pos);
}
// string_view::find_last_not_of()
//
// Finds the last occurrence of any of the characters not in `s` within the
// `string_view`, returning the start position of the last non-match, or
// `npos` if no non-match was found.
size_type find_last_not_of(string_view s,
size_type pos = npos) const noexcept;
// Overload of `string_view::find_last_not_of()` for finding a character
// that is not `c` within the `string_view`.
size_type find_last_not_of(char c, size_type pos = npos) const noexcept;
// Overload of `string_view::find_last_not_of()` for finding a substring of a
// different C-style string `s` within the `string_view`.
size_type find_last_not_of(const char* s, size_type pos,
size_type count) const {
return find_last_not_of(string_view(s, count), pos);
}
// Overload of `string_view::find_last_not_of()` for finding a different
// C-style string `s` within the `string_view`.
size_type find_last_not_of(const char* s, size_type pos = npos) const {
return find_last_not_of(string_view(s), pos);
}
private:
// The constructor from std::string delegates to this constructor.
// See the comment on that constructor for the rationale.
struct SkipCheckLengthTag {};
string_view(const char* data, size_type len, SkipCheckLengthTag) noexcept
: ptr_(data), length_(len) {}
static constexpr size_type kMaxSize =
(std::numeric_limits<difference_type>::max)();
static constexpr size_type CheckLengthInternal(size_type len) {
return ABSL_HARDENING_ASSERT(len <= kMaxSize), len;
}
static constexpr size_type StrlenInternal(const char* str) {
#if defined(_MSC_VER) && _MSC_VER >= 1910 && !defined(__clang__)
// MSVC 2017+ can evaluate this at compile-time.
const char* begin = str;
while (*str != '\0') ++str;
return str - begin;
#elif ABSL_HAVE_BUILTIN(__builtin_strlen) || \
(defined(__GNUC__) && !defined(__clang__))
// GCC has __builtin_strlen according to
// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Other-Builtins.html, but
// ABSL_HAVE_BUILTIN doesn't detect that, so we use the extra checks above.
// __builtin_strlen is constexpr.
return __builtin_strlen(str);
#else
return str ? strlen(str) : 0;
#endif
}
static constexpr size_t Min(size_type length_a, size_type length_b) {
return length_a < length_b ? length_a : length_b;
}
static constexpr int CompareImpl(size_type length_a, size_type length_b,
int compare_result) {
return compare_result == 0 ? static_cast<int>(length_a > length_b) -
static_cast<int>(length_a < length_b)
: (compare_result < 0 ? -1 : 1);
}
const char* ptr_;
size_type length_;
};
// This large function is defined inline so that in a fairly common case where
// one of the arguments is a literal, the compiler can elide a lot of the
// following comparisons.
constexpr bool operator==(string_view x, string_view y) noexcept {
return x.size() == y.size() &&
(x.empty() ||
ABSL_INTERNAL_STRING_VIEW_MEMCMP(x.data(), y.data(), x.size()) == 0);
}
constexpr bool operator!=(string_view x, string_view y) noexcept {
return !(x == y);
}
constexpr bool operator<(string_view x, string_view y) noexcept {
return x.compare(y) < 0;
}
constexpr bool operator>(string_view x, string_view y) noexcept {
return y < x;
}
constexpr bool operator<=(string_view x, string_view y) noexcept {
return !(y < x);
}
constexpr bool operator>=(string_view x, string_view y) noexcept {
return !(x < y);
}
// IO Insertion Operator
std::ostream& operator<<(std::ostream& o, string_view piece);
ABSL_NAMESPACE_END
} // namespace absl
#undef ABSL_INTERNAL_STRING_VIEW_CXX14_CONSTEXPR
#undef ABSL_INTERNAL_STRING_VIEW_MEMCMP
#endif // ABSL_USES_STD_STRING_VIEW
namespace absl {
ABSL_NAMESPACE_BEGIN
// ClippedSubstr()
//
// Like `s.substr(pos, n)`, but clips `pos` to an upper bound of `s.size()`.
// Provided because std::string_view::substr throws if `pos > size()`
inline string_view ClippedSubstr(string_view s, size_t pos,
size_t n = string_view::npos) {
pos = (std::min)(pos, static_cast<size_t>(s.size()));
return s.substr(pos, n);
}
// NullSafeStringView()
//
// Creates an `absl::string_view` from a pointer `p` even if it's null-valued.
// This function should be used where an `absl::string_view` can be created from
// a possibly-null pointer.
constexpr string_view NullSafeStringView(const char* p) {
return p ? string_view(p) : string_view();
}
ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_STRINGS_STRING_VIEW_H_
八、十进制转十六进制 c语言
#include <stdio.h>
/*输入一个十进制整数(可能大于15),转化为十六进制输出*/
/*十进制转十六进制,方法:除16取余数倒排
取余结果放入到str1,倒排结果放入到str2
*/
char* convert(int x)
{
static char hexchars[] = "0123456789ABCDEF"; //十六进制对应的数组
static char str1[81], str2[81], * p = str1, * q = str2;
static int n = 0; //计算字符长度,为倒排做准备
//str1 存储取余数组, str2倒排存储数组
while (x) //取余
{
*p++ = hexchars[x % 16];
x /= 16;
n++;
}
p--; //指针回退,因为多加了一步
while (n)
{
*q++ = *p--;
n--;
}
return str2;
}
int main()
{
int x;
printf("请输入一个十进制数:\n");
scanf("%d", &x);
printf("对应的十六进制数是:%s\n", convert(x));
return 0;
}
九、十进制转十六进制 c语言
#include"stdio.h"
#include"stdlib.h"
int main(void) {
int n,a1,count=0,j;//count 用于角标的计数,j 控制 for 循环
int a[100];
printf("Entern:");
scanf("%d",&n);
if(n==0)
printf("%d",n);
while(n!=0) {
a1=n;
n=n/16;
a[count]=a1%16;
count++;
}
for(j=count-1;j>=0;j--) {
if(a[j]>9&&a[j]<16)
printf("%c",(a[j]-10+'A'));
else
printf("%d",a[j]);
}
printf("\n");
return 0;
}
十、十进制转十六进制 c++
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
typedef long long ll;
//十进制转十六进制
string s; //存放十六进制的字符串
int main() {
ll x;
cin>>x;
while(x){
int remainder = x%16; //拿到余数,对余数进行处理
x = x/16; //这两步可以对比以十进制获取一个整数的每一位
if(remainder < 10){
s += remainder + '0'; //将整数转为字符
}else{
s += remainder - 10 + 'A';
}
}
reverse(s.begin(),s.end()); //最后要进行翻转
cout<<s<<endl;
return 0;
}