我有一个这样的字符串:
"00c4"
我需要将它转换为字面值所表示的数值:
0x00c4
我该怎么做?
stdlib.h
中的 strtol
函数(或者无符号长整型的 strtoul
函数),可以帮助您将一个字符串按指定进制转换为长整型。因此,以下代码可以实现这个功能:
char *s = "00c4";
char *e;
long int i = strtol (s, &e, 16);
// Check that *e == '\0' assuming your string should ONLY
// contain hex digits.
// Also check errno == 0.
// You can also just use NULL instead of &e if you're sure of the input.
#include <iostream>
#include <sstream>
#include <stdexcept>
class bad_conversion : public std::runtime_error
{
public:
bad_conversion(std::string const& s)
: std::runtime_error(s)
{ }
};
template<typename T>
inline void convert_from_hex_string(std::string const& s, T& x,
bool failIfLeftoverChars = true)
{
std::istringstream i(s);
char c;
if (!(i >> std::hex >> x) || (failIfLeftoverChars && i.get(c)))
throw ::bad_conversion(s);
}
int main(int argc, char* argv[])
{
std::string blah = "00c4";
int input;
::convert_from_hex_string(blah, input);
std::cout << std::hex << input << "\n";
return 0;
}
i >> std::hex >> x >> std::ws
,这样尾随的空格就不会触发异常了。 - sbistd::ios_base& (*)(std::ios_base&)
作为参数。 - sbifailIfLeftoverChars
设为 enum
并允许第三个选项。 - sbi#include <stdio.h>
int main()
{
const char *str = "0x00c4";
int i = 0;
sscanf(str, "%x", &i);
printf("%d = 0x%x\n", i, i);
return 0;
}
%x
时,输入字符串无需以0x
为前缀。如果您使用%i
而不是%x
,它将接受十进制、十六进制或八进制输入,其中十六进制输入必须以0x
为前缀,八进制则以0
为前缀。此外,考虑到C++标签,可以提出使用<sstream>
的类似解决方案。 - Clifford"blah"
作为str
传递给sscanf()
会发生什么? - sbistd::string val ="00c4";
uint16_t out;
if( (std::istringstream(val)>>std::hex>>out).fail() )
{ /*error*/ }
实际上并不存在所谓的“实际十六进制值”。一旦你进入本地数据类型,你就处于二进制状态。从十六进制字符串转换到二进制是在上面讨论过的。将其显示为十六进制输出也是如此。但它并不是一个“实际的十六进制值”。它只是二进制。
int val_from_hex(char *hex_string) {
char *c = hex_string;
int val = 0;
while(*c) {
val <<= 4;
if(*c >= '0' && *c <= '9')
val += *c - '0';
else if(*c >= 'a' && *c <= 'f')
val += *c - 'a' + 10;
c++;
}
return val;
}
*e == '\0'
,检查e == s+strlen(s)
就有点过了。 - nothrow8
到f
开头的数字),它们可能会被扩展成负数。使用strtoul
可能更安全。 - paxdiablo