为了将一个C风格的以null结尾的字符串转换为一个数据类型为unsigned long long的整数,可以使用函数std::stoull。 然后可以将unsigned long long类型的值强制转换为uint64_t类型,因为标准保证unsigned long long足够大,可以表示uint64_t的所有可能值。 下面是一个例子:
#include <iostream>
#include <cstdlib>
#include <cstdint>
#include <limits>
int main()
{
const char *input = "0xC45AC8";
char *endptr;
unsigned long long result1;
uint64_t result2;
//attempt to convert string input to an integer
result1 = std::strtoull( input, &endptr, 16 );
if ( endptr == input )
{
std::cout << "Failed to convert input!\n";
return EXIT_FAILURE;
}
//verify that the result is representable in
//the type uint64_t
if ( result1 > std::numeric_limits<uint64_t>::max() )
{
std::cout << "Value is out of range of a uint64_t!\n";
return EXIT_FAILURE;
}
//convert the result to the desired type
result2 = static_cast<uint64_t>(result1);
//print the result
std::cout <<
"Input successfully converted to uint64_t!\n"
"The result is: " << std::hex << result2;
}
此程序具有以下输出:
Input successfully converted to uint64_t!
The result is: c45ac8
template <class T>
T convert_hex_string_to(const char* first) {
return convert_hex_string_to<T>(first, first + std::strlen(first));
}
做繁重工作的过载可能看起来像这样:
template <class T>
T convert_hex_string_to(const char* first, const char* last) {
T result;
if (std::distance(first, last) <= 2) // we need at least 2 chars for "0x"
throw std::invalid_argument(
std::string(first, last) +
" is a few characters short of a full hex string");
// ... and they must be "0x" or "0X"
if (*first != '0' ||
std::tolower(static_cast<unsigned char>(first[1])) != 'x')
throw std::invalid_argument(std::string(first, last) +
" is not a hex valid hex string");
// ok, enough checking, lets try to convert:
auto [ptr, ec] = std::from_chars(first + 2, last, result, 16);
if (ec == std::errc{}) { // no error - now just check if the whole string
// was used in the conversion:
// ptr should be equal to last if the whole string was consumed during
// conversion:
if (ptr != last)
throw std::runtime_error("garbage in input: " +
std::string(ptr, last));
} else {
// an error occured, let's throw something friendly if we can:
switch (ec) {
case std::errc::result_out_of_range:
throw std::out_of_range(
std::string(first, last) +
" has a value out of range for the target type");
case std::errc::invalid_argument:
throw std::invalid_argument(std::string(first, last) +
" is not a hex valid hex string");
default:
throw std::invalid_argument(
std::string(first, last) +
" is wrong in ways I don't know how to describe");
}
}
return result;
}
2条答案
按热度按时间jgovgodb1#
为了将一个C风格的以null结尾的字符串转换为一个数据类型为
unsigned long long
的整数,可以使用函数std::stoull
。然后可以将
unsigned long long
类型的值强制转换为uint64_t
类型,因为标准保证unsigned long long
足够大,可以表示uint64_t
的所有可能值。下面是一个例子:
此程序具有以下输出:
qltillow2#
hex_offset
将携带字符串字面量"0xC45AC8"
中第一个字符的地址的值表示-这不太可能是您想要的值。你需要以某种方式解释字符串字面量。
std::from_chars
是C++17中的一个很好的添加。它意味着速度快,不会抛出异常,所以你必须添加错误处理。我在下面展示了你可以通过手动抛出异常来处理错误的地方。我会选择这个接口:
通过将
convert_hex_string_to
转换为函数模板,可以将任何C字符串转换为我们选择的类型。说我们要将C字符串
offset
转换为std::uint64_t
。该函数模板的第一个实现是一个重载,它只计算C字符串的结尾,并将其传递给另一个重载:
做繁重工作的过载可能看起来像这样:
Demo