c++ 如何将%{v_扩展}转换为uint64_t

iswrvxsc  于 2023-04-08  发布在  其他
关注(0)|答案(2)|浏览(92)

我是c++的初学者。我有一个char数组偏移量。我需要将char数组转换为uint64_t。事实上,需要删除括号并将其写入hex_offset。

char * offset = {"0xC45AC8"};
uint64_t hex_offset = (uint64_t) offset;
jgovgodb

jgovgodb1#

为了将一个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
qltillow

qltillow2#

char * offset = {"0xC45AC8"};             // invalid, should be `const char*`
uint64_t hex_offset = (uint64_t) offset;  // fine, but probably not what you want.

hex_offset将携带字符串字面量"0xC45AC8"中第一个字符的地址的值表示-这不太可能是您想要的值。
你需要以某种方式解释字符串字面量。std::from_chars是C++17中的一个很好的添加。它意味着速度快,不会抛出异常,所以你必须添加错误处理。我在下面展示了你可以通过手动抛出异常来处理错误的地方。
我会选择这个接口:

template <class T>
T convert_hex_string_to(const char* first); // implementation comes later

int main() {
    const char* offset = {"0xC45AC8"};

    auto hex_offset = convert_hex_string_to<std::uint64_t>(offset);

    std::cout << std::hex << hex_offset << '\n';
}

通过将convert_hex_string_to转换为函数模板,可以将任何C字符串转换为我们选择的类型。

auto hex_offset = convert_hex_string_to<std::uint64_t>(offset);

说我们要将C字符串offset转换为std::uint64_t
该函数模板的第一个实现是一个重载,它只计算C字符串的结尾,并将其传递给另一个重载:

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;
}

Demo

相关问题