Nhờ nhận xét của Lincoln bên dưới, tôi đã thay đổi câu trả lời này.
Câu trả lời sau xử lý đúng 8 bit int tại thời điểm biên dịch. Tuy nhiên, nó yêu cầu C ++ 17. Nếu bạn không có C ++ 17, bạn sẽ phải làm điều gì đó khác (ví dụ: cung cấp quá tải của hàm này, một cho uint8_t và một cho int8_t hoặc sử dụng một cái gì đó ngoài "if constexpr", có thể enable_if).
template< typename T >
std::string int_to_hex( T i )
{
// Ensure this function is called with a template parameter that makes sense. Note: static_assert is only available in C++11 and higher.
static_assert(std::is_integral<T>::value, "Template argument 'T' must be a fundamental integer type (e.g. int, short, etc..).");
std::stringstream stream;
stream << "0x" << std::setfill ('0') << std::setw(sizeof(T)*2) << std::hex;
// If T is an 8-bit integer type (e.g. uint8_t or int8_t) it will be
// treated as an ASCII code, giving the wrong result. So we use C++17's
// "if constexpr" to have the compiler decides at compile-time if it's
// converting an 8-bit int or not.
if constexpr (std::is_same_v<std::uint8_t, T>)
{
// Unsigned 8-bit unsigned int type. Cast to int (thanks Lincoln) to
// avoid ASCII code interpretation of the int. The number of hex digits
// in the returned string will still be two, which is correct for 8 bits,
// because of the 'sizeof(T)' above.
stream << static_cast<int>(i);
}
else if (std::is_same_v<std::int8_t, T>)
{
// For 8-bit signed int, same as above, except we must first cast to unsigned
// int, because values above 127d (0x7f) in the int will cause further issues.
// if we cast directly to int.
stream << static_cast<int>(static_cast<uint8_t>(i));
}
else
{
// No cast needed for ints wider than 8 bits.
stream << i;
}
return stream.str();
}
Câu trả lời ban đầu không xử lý đúng 8 bit int như tôi nghĩ:
Câu trả lời của Kornel Kisielewicz rất tuyệt. Nhưng một bổ sung nhỏ giúp giải quyết các trường hợp bạn đang gọi hàm này với các đối số mẫu không hợp lý (ví dụ: float) hoặc điều đó sẽ dẫn đến lỗi trình biên dịch lộn xộn (ví dụ: kiểu do người dùng xác định).
template< typename T >
std::string int_to_hex( T i )
{
// Ensure this function is called with a template parameter that makes sense. Note: static_assert is only available in C++11 and higher.
static_assert(std::is_integral<T>::value, "Template argument 'T' must be a fundamental integer type (e.g. int, short, etc..).");
std::stringstream stream;
stream << "0x"
<< std::setfill ('0') << std::setw(sizeof(T)*2)
<< std::hex << i;
// Optional: replace above line with this to handle 8-bit integers.
// << std::hex << std::to_string(i);
return stream.str();
}
Tôi đã chỉnh sửa điều này để thêm lệnh gọi tới std :: to_string vì các kiểu số nguyên 8 bit (ví dụ: std::uint8_t
giá trị được truyền) std::stringstream
được coi là char, điều này không cung cấp cho bạn kết quả như mong muốn. Chuyển các số nguyên như vậy để std::to_string
xử lý chúng một cách chính xác và không làm ảnh hưởng đến mọi thứ khi sử dụng các kiểu số nguyên lớn hơn, khác. Tất nhiên, bạn có thể bị ảnh hưởng hiệu suất nhẹ trong những trường hợp này vì lệnh gọi std :: to_string là không cần thiết.
Lưu ý: Tôi sẽ chỉ thêm điều này trong một bình luận vào câu trả lời ban đầu, nhưng tôi không có đại diện để bình luận.
int
loại;)