如何在C++中将整数转换为十六进制字符串?
我可以找到一些方法来做到这一点,但它们大多似乎针对C语言。似乎在C++中没有本地方式来实现它。不过这是一个非常简单的问题;我有一个int
,我想将其转换为十六进制字符串以便稍后打印。
<iomanip>
的std::hex
。如果要打印,请将其发送到std::cout
,否则请使用std::stringstream
。std::stringstream stream;
stream << std::hex << your_int;
std::string result( stream.str() );
<<
前加上<< "0x"
或任何你喜欢的内容。
其他有用的操作包括std::oct
(八进制)和std::dec
(回到十进制)。
你可能会遇到的一个问题是,这会生成表示它所需的确切位数。你可以使用setfill
和setw
来解决这个问题:
stream << std::setfill ('0') << std::setw(sizeof(your_type)*2)
<< std::hex << your_int;
所以,最终我建议使用这样的一个函数:
template< typename T >
std::string int_to_hex( T i )
{
std::stringstream stream;
stream << "0x"
<< std::setfill ('0') << std::setw(sizeof(T)*2)
<< std::hex << i;
return stream.str();
}
std::format
实现。std::string s = std::format("{:x}", 42); // s == 2a
在 std::format
得到广泛应用之前,您可以使用 {fmt} 库,std::format
是基于此开发的(参见godbolt):
std::string s = fmt::format("{:x}", 42); // s == 2a
免责声明:我是{fmt}和C++20 std::format
的作者。
0x
(十六进制)或0o
(八进制)前缀?例如,如果我想要0x002a
或0o52
,应该怎么做? - 0xdeadbeef0x002a
,您可以使用"{:#06x}"
;对于0o52
,您可以使用"0o{:o}"
。这种语法非常丰富和灵活。 - undefinedtemplate <typename I> std::string n2hexstr(I w, size_t hex_len = sizeof(I)<<1) {
static const char* digits = "0123456789ABCDEF";
std::string rc(hex_len,'0');
for (size_t i=0, j=(hex_len-1)*4 ; i<hex_len; ++i,j-=4)
rc[i] = digits[(w>>j) & 0x0f];
return rc;
}
double
和 float
(也不适用于指针) - Wolf0000FFFF
作为 0xFFFF
的输出。我更喜欢将 0xFFFF
作为输出。 - jaques-sam使用 std::stringstream
将整数转换为字符串,并使用其特殊操作符来设置进制。例如:
std::stringstream sstream;
sstream << std::hex << my_integer;
std::string result = sstream.str();
将其作为十六进制数打印:
int i = /* ... */;
std::cout << std::hex << i;
std::cout<<std::hex<<i<<std::dec;
,那么后面流出的所有整数都将是十六进制的。对于使用stringstream
的其他答案则不需要这样做,因为流在使用后会被丢弃,但cout
会一直存在。 - Mark LakataC++20引入了std::format
,你可以这样使用:
std::format("{:#x}", your_int); // 0x2a
std::format("{:#010x}", your_int); // 0x0000002a
#include <boost/format.hpp>
...
cout << (boost::format("%x") % 1234).str(); // output is: 4d2
#include <boost/format.hpp>
。 - Wade Wang#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace std;
template <class T>
string to_string(T t, ios_base & (*f)(ios_base&))
{
ostringstream oss;
oss << f << t;
return oss.str();
}
int main ()
{
cout<<to_string<long>(123456, hex)<<endl;
system("PAUSE");
return 0;
}
to_string
是std
命名空间的一部分。 - Alexander Oh<charconv>
的 std::to_chars
(https://en.cppreference.com/w/cpp/utility/to_chars):char addressStr[20] = { 0 };
std::to_chars(std::begin(addressStr), std::end(addressStr), address, 16);
return std::string{addressStr};
std::to_chars
使用预分配的缓冲区来避免动态分配,但这也让你可以优化代码,因为如果在热点中进行动态分配会非常昂贵。to_chars
的返回值以检查错误并获取写入数据的长度。注意:to_chars
不会写入空终止符!请看一下我的解决方案[1],这是我直接从项目中复制的。我的目标是在满足实际需求的同时,结合灵活性和安全性:[3]
0x
前缀:调用者可以决定long long
#include <string>
#include <sstream>
#include <iomanip>
/// Convert integer value `val` to text in hexadecimal format.
/// The minimum width is padded with leading zeros; if not
/// specified, this `width` is derived from the type of the
/// argument. Function suitable from char to long long.
/// Pointers, floating point values, etc. are not supported;
/// passing them will result in an (intentional!) compiler error.
/// Basics from: https://dev59.com/Qm435IYBdhLWcg3w-1V_#5100745
template <typename T>
inline std::string int_to_hex(T val, size_t width=sizeof(T)*2)
{
std::stringstream ss;
ss << std::setfill('0') << std::setw(width) << std::hex << (val|0);
return ss.str();
}
[1] 基于 Kornel Kisielewicz 的答案。
[2] 只有德文版的API文档被翻译成了英文。
[3] 翻译成CppTest语言后,它的含义如下:
TEST_ASSERT(int_to_hex(char(0x12)) == "12");
TEST_ASSERT(int_to_hex(short(0x1234)) == "1234");
TEST_ASSERT(int_to_hex(long(0x12345678)) == "12345678");
TEST_ASSERT(int_to_hex((long long)(0x123456789abcdef0)) == "123456789abcdef0");
TEST_ASSERT(int_to_hex(0x123, 1) == "123");
TEST_ASSERT(int_to_hex(0x123, 8) == "00000123");
// width deduction test as suggested by Lightness Races in Orbit:
TEST_ASSERT(int_to_hex(short(0x12)) == "0012");
TEST_ASSERT(int_to_hex(short(0x12)) == "0012");
来展示宽度推断。 - Lightness Races in Orbit
std::showbase
会显示一个0x
前缀... - quaylarstd::setw
输出到流中,而std::hex
、std::setfill
、std::uppercase
等只需要发送一次到输出流中。这看起来不一致? - wcochran