Ayr*_*osa 51 c++ io iostream iomanip
如何使用cout打印0x0a而不是0xa?
#include <iostream>
using std::cout;
using std::endl;
using std::hex;
int main()
{
cout << hex << showbase << 10 << endl;
}
Run Code Online (Sandbox Code Playgroud)
Emi*_*ier 85
这适用于GCC:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << "0x" << setfill('0') << setw(2) << hex << 10 << endl;
}
Run Code Online (Sandbox Code Playgroud)
如果你厌倦了iostream格式化的怪癖,那么试试Boost.Format吧.它允许使用老式的printf样式格式说明符,但它是类型安全的.
#include <iostream>
#include <boost/format.hpp>
int main()
{
std::cout << boost::format("0x%02x\n") % 10;
}
Run Code Online (Sandbox Code Playgroud)
Dou*_* T. 20
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
using std::hex;
int main()
{
cout << "0x" << std::setfill('0') << std::setw(2) << hex << 10 << endl;
}
Run Code Online (Sandbox Code Playgroud)
就个人而言,iostreams的有状态性质总是让我烦恼.我认为提升格式是一个更好的选择,所以我建议另一个答案.
如果您想更简单地输出十六进制数,可以编写如下函数:
更新版本如下; 0x可以通过两种方式插入基本指示器,并使用脚注详细说明它们之间的差异.原始版本保留在答案的底部,以免给使用它的任何人带来不便.
请注意,更新版本和原始版本可能需要针对字节大小为9位的倍数的系统进行一些定制.
#include <type_traits> // For integral_constant, is_same.
#include <string> // For string.
#include <sstream> // For stringstream.
#include <ios> // For hex, internal, [optional] showbase.
// Note: <ios> is unnecessary if <iostream> is also included.
#include <iomanip> // For setfill, setw.
#include <climits> // For CHAR_BIT.
namespace detail {
constexpr int HEX_DIGIT_BITS = 4;
//constexpr int HEX_BASE_CHARS = 2; // Optional. See footnote #2.
// Replaced CharCheck with a much simpler trait.
template<typename T> struct is_char
: std::integral_constant<bool,
std::is_same<T, char>::value ||
std::is_same<T, signed char>::value ||
std::is_same<T, unsigned char>::value> {};
}
template<typename T>
std::string hex_out_s(T val) {
using namespace detail;
std::stringstream sformatter;
sformatter << std::hex
<< std::internal
<< "0x" // See footnote #1.
<< std::setfill('0')
<< std::setw(sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) // See footnote #2.
<< (is_char<T>::value ? static_cast<int>(val) : val);
return sformatter.str();
}
Run Code Online (Sandbox Code Playgroud)
它可以使用如下:
uint32_t hexU32 = 0x0f;
int hexI = 0x3c;
unsigned short hexUS = 0x12;
std::cout << "uint32_t: " << hex_out_s(hexU32) << '\n'
<< "int: " << hex_out_s(hexI) << '\n'
<< "unsigned short: " << hex_out_s(hexUS) << std::endl;
Run Code Online (Sandbox Code Playgroud)
实时:在这里查看两个选项(如脚注中所详述).
脚注:
此行负责显示基数,可以是以下任一项:
<< "0x"
<< std::showbase
Run Code Online (Sandbox Code Playgroud)
对于尝试输出负十六进制数-0x##而不是as的自定义类型,第一个选项将显示不正确<complement of 0x##>,其中符号显示在base(as 0x-##)之后而不是之前.这很少是一个问题,所以我个人更喜欢这个选项.
如果这是一个问题,那么在使用这些类型时,您可以在输出基数之前检查否定性,然后使用abs()(或者返回无符号值的自定义abs(),如果您需要能够处理2的最负值)补充系统)val.
第二个选项将省略val == 0显示(例如,for int,where int32位)0000000000而不是预期的基数0x00000000.这是因为showbase标志在内部被视为printf()'s #修饰符.
如果这是一个问题,您可以检查是否val == 0,并在此时应用特殊处理.
根据选择显示基数的选项,需要更改两行.
<< "0x",则HEX_BASE_CHARS不需要,可以省略.如果使用<< std::showbase,则提供的值setw()需要考虑到:
<< std::setw((sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) + HEX_BASE_CHARS)
Run Code Online (Sandbox Code Playgroud)原始版本如下:
// Helper structs and constants for hex_out_s().
namespace hex_out_helper {
constexpr int HEX_DIGIT_BITS = 4; // One hex digit = 4 bits.
constexpr int HEX_BASE_CHARS = 2; // For the "0x".
template<typename T> struct CharCheck {
using type = T;
};
template<> struct CharCheck<signed char> {
using type = char;
};
template<> struct CharCheck<unsigned char> {
using type = char;
};
template<typename T> using CharChecker = typename CharCheck<T>::type;
} // namespace hex_out_helper
template<typename T> std::string hex_out_s(T val) {
using namespace hex_out_helper;
std::stringstream sformatter;
sformatter << std::hex
<< std::internal
<< std::showbase
<< std::setfill('0')
<< std::setw((sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) + HEX_BASE_CHARS)
<< (std::is_same<CharChecker<T>, char>{} ? static_cast<int>(val) : val);
return sformatter.str();
}
Run Code Online (Sandbox Code Playgroud)
然后可以像这样使用:
uint32_t hexU32 = 0x0f;
int hexI = 0x3c;
unsigned short hexUS = 0x12;
std::cout << hex_out_s(hexU32) << std::endl;
std::cout << hex_out_s(hexI) << std::endl;
std::cout << "And let's not forget " << hex_out_s(hexUS) << std::endl;
Run Code Online (Sandbox Code Playgroud)
工作示例:这里.
在 C++20 中,您可以使用std::format以下方法来执行此操作:
std::cout << std::format("{:02x}\n", 10);
Run Code Online (Sandbox Code Playgroud)
输出:
0a
Run Code Online (Sandbox Code Playgroud)
同时您可以使用基于的{fmt} 库std::format。{fmt} 还提供了print使这变得更容易、更高效的函数 ( godbolt ):
fmt::print("{:02x}\n", 10);
Run Code Online (Sandbox Code Playgroud)
免责声明:我是 {fmt} 和 C++20 的作者std::format。