我有一个十六进制字符串,想将其转换为十六进制无符号字符数组!
std::string hex = "0c45a1bf"
unsigned char hexCh = ""
[0] = "0c"
[1] = "45"
[2] = "a1"
[3] = "bf"
我希望以 hexCh 显示这种行为!
stringstream 和 std::hex 的最佳方法?你有实现吗?!
谢谢
假设您想要每对十六进制字符串的值:
std::string hex = "0c45a1bf";
int main(int argc, char **argv)
{
union U
{
unsigned int value;
unsigned char components[4];
};
U u;
std::stringstream SS(hex);
SS >> std::hex >> u.value;
std::cout << u.components[0] << '\n'; // the 0c value
std::cout << u.components[1] << '\n'; // the 45 value
std::cout << u.components[2] << '\n'; // the a1 value
std::cout << u.components[3] << '\n'; // the bf value
}
您可以将值读入 anunion
并获取每个子部分。
使用std::stringstream
+ std::hex
:
std::stringstream ss;
std::string hex = "0c45a1bf";
std::vector<unsigned char> hexCh;
unsigned int buffer;
int offset = 0;
while (offset < hex.length()) {
ss.clear();
ss << std::hex << hex.substr(offset, 2);
ss >> buffer;
hexCh.push_back(static_cast<unsigned char>(buffer));
offset += 2;
}
您可以将整个字符串转换为更大的整数类型,然后从中挑选出字节。就像是:
std::vector<unsigned char>
asBytes( std::string const& input )
{
std::istringstream parser( input );
uint32_t tmp;
input >> std::hex >> tmp;
std::vector<unsigned char> results;
// The conversion implicitly does the & 0xFF
results.push_back( tmp >> 24 );
results.push_back( tmp >> 16 );
results.push_back( tmp >> 8 );
results.push_back( tmp );
return results;
}
或者,您可以创建每个包含两个字符的子字符串,std::istringstream
为每个字符创建一个,然后从中输入。您仍然必须输入大于 的类型char
,因为>>
字符类型仅读取一个字符并分配它。但是您可以将其读入int
,然后将其转换int
为
unsigned char
。
unsigned char
convertOneByte( std::string::const_iterator begin,
std::string::const_iterator end )
{
std::istringstream parser( std::string( begin, end ) );
int tmp;
parser >> std::hex >> tmp;
return tmp;
}
std::vector<unsigned char>
asBytes( std::string const& input )
{
std::vector<unsigned char> results;
results.push_back( input.begin() , input.begin() + 2 );
results.push_back( input.begin() + 2, input.begin() + 4 );
results.push_back( input.begin() + 4, input.begin() + 6 );
results.push_back( input.begin() + 6, input.begin() + 8 );
return results;
}
(这两段代码都需要更多的错误检查。它们只是为了给你一个想法。)
这两个功能一起完成工作:
这个很简单:
inline int char2hex(char c)
{
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
throw std::runtime_error("wrong char");
}
这有点复杂:
std::vector<unsigned char> str2hex(const std::string& hexStr)
{
std::vector<unsigned char> retVal;
bool highPart = ((hexStr.length() % 2) == 0);
// for odd number of characters - we add an extra 0 for the first one:
if (!highPart)
retVal.push_back(0);
std::for_each(hexStr.begin(), hexStr.end(),
[&](char nextChar) {
if (highPart)
// this is first char for the given hex number:
retVal.push_back(0x10 * char2hex(nextChar));
else
// this is the second char for the given hex number
retVal.back() += char2hex(nextChar);
highPart = !highPart;
}
);
return retVal;
}
它的工作示例:
int main() {
std::string someHex = "c45a1bf";
std::vector<unsigned char> someUHex = str2hex(someHex);
std::copy(someUHex.begin(), someUHex.end(), std::ostream_iterator<int>(std::cout << std::hex, ""));
}
一个可能的解决方案:(感谢 Denis Ermolin):
void ClassA::FuncA(unsigned char *answer)
{
std::string hex = "0c45a1bf";
std::stringstream convertStream;
// if you have something like "0c 45 a1 bf" -> delete blanks
hex.erase( std::remove(hex.begin(), hex.end(), ' '), hex.end() );
int offset = 0, i = 0;
while (offset < hex.length())
{
unsigned int buffer;
convertStream << std::hex << hex.substr(offset, 2);
convertStream >> std::hex >> buffer;
answer[i] = static_cast<unsigned char>(buffer);
offset += 2;
i++;
// empty the stringstream
convertStream.str(std::string());
convertStream.clear();
}
}