C++ cout 十六进制值?
Posted
技术标签:
【中文标题】C++ cout 十六进制值?【英文标题】:C++ cout hex values? 【发布时间】:2010-10-03 12:33:30 【问题描述】:我想做:
int a = 255;
cout << a;
让它在输出中显示 FF,我该怎么做?
【问题讨论】:
【参考方案1】:用途:
#include <iostream>
...
std::cout << std::hex << a;
有many other options to control the exact formatting of the output number,比如前导零和大小写。
【讨论】:
这似乎将所有未来的输出从 cout 更改为 hex;因此,如果您只想以十六进制打印“a”,则可能需要cout << hex << a << dec;
之类的内容将其改回。
@ShreevatsaR 通过十六进制恢复 dec 的一个问题是 dec 可能不是之前设置的值,尤其是在您编写通用库方法时。 This question 有一些关于如何存储和恢复状态的答案。您可以使用ios::fmtflags f(cout.flags());
保存状态并使用out.flags(f);
恢复它。
然后通过std::cout.flags(f);
恢复【参考方案2】:
std::hex
定义在<ios>
中,它包含在<iostream>
中。但是要使用 std::setprecision/std::setw/std::setfill
/etc 之类的东西,您必须包含 <iomanip>
。
【讨论】:
【参考方案3】:要操纵流以十六进制打印,请使用 hex
操纵器:
cout << hex << a;
默认情况下,十六进制字符以小写形式输出。要将其更改为大写,请使用 uppercase
操纵器:
cout << hex << uppercase << a;
若要稍后将输出改回小写,请使用nouppercase
操纵器:
cout << nouppercase << b;
【讨论】:
nouppercase
会把输出改回十进制吗?
只是为了添加杂项,上面的sn-p不会使输入“apple”变成“APPLE”。【参考方案4】:
如果你想打印一个十六进制数字,然后恢复为十进制,你可以使用这个:
std::cout << std::hex << num << std::dec << std::endl;
【讨论】:
【参考方案5】:std::hex
为您提供十六进制格式,但它是一个有状态选项,这意味着您需要保存和恢复状态,否则它将影响所有未来的输出。
天真地切换回 std::dec
只有在以前的标志位置才有用,但情况可能并非如此,尤其是在您编写库时。
#include <iostream>
#include <ios>
...
std::ios_base::fmtflags f( cout.flags() ); // save flags state
std::cout << std::hex << a;
cout.flags( f ); // restore flags state
这结合了 Greg Hewgill 的答案和来自 another question 的信息。
【讨论】:
【参考方案6】:我知道这不是 OP 所要求的,但我仍然认为值得指出如何使用 printf 来做到这一点。我几乎总是更喜欢使用它而不是 std::cout(即使没有以前的 C 背景)。
printf("%.2X", a);
'2' 定义精度,'X' 或 'x' 定义大小写。
【讨论】:
printf 与 cout 的战斗由来已久。当然,cout 具有从 ostream 派生的良好属性,并获得所有抽象优势。 C 没有流对象的概念,因此 printf 和 fprintf 是两个不同的命令。真的,如果 stdout 是 FILE* 在 C 语言中会很好。会让事情变得更容易。 @rlbond 标准输出是 C 中的 FILE *。 这就是为什么printf("hello\n")
等同于fprintf(stdout, "hello\n")
。更有用的是,您可以将stdout
(或stdin
,或stderr
)传递给采用FILE*
参数的函数。【参考方案7】:
您也可以使用不同种类的标志和掩码。更多信息请参考http://www.cplusplus.com/reference/iostream/ios_base/setf/。
#include <iostream>
using namespace std;
int main()
int num = 255;
cout.setf(ios::hex, ios::basefield);
cout << "Hex: " << num << endl;
cout.unsetf(ios::hex);
cout << "Original format: " << num << endl;
return 0;
【讨论】:
我认为这段代码的行为是未定义的。 setf 清除 ios::basefield 位,包括 ios::dec(标准流的默认值),并且只设置 ios::hex。当 ios::hex 未设置时,ios::basefield 中的每一位都未设置。它是如何 num 第二次打印的?这些位都未设置的证据:ideone.com/fYXyh6。根据 Thinking in C++ vol 2 page 189,这对于 ios::floatfield 是允许的,但对于 ios::basefield 并没有说同样的话。【参考方案8】:使用std::uppercase
和std::hex
格式化整数变量a
以十六进制格式显示。
#include <iostream>
int main()
int a = 255;
// Formatting Integer
std::cout << std::uppercase << std::hex << a << std::endl; // Output: FF
std::cout << std::showbase << std::hex << a << std::endl; // Output: 0XFF
std::cout << std::nouppercase << std::showbase << std::hex << a << std::endl; // Output: 0xff
return 0;
【讨论】:
【参考方案9】:C++20 std::format
这是我认为现在最干净的方法,因为它不会污染std::cout
状态和std::hex
:
main.cpp
#include <format>
#include <string>
int main()
std::cout << std::format(":x :#x \n", 16, 17, 18);
预期输出:
10 0x11 18
尚未在 GCC 10.0.1、Ubuntu 20.04 上实现。
但是成为 C++20 的很棒的库,一旦安装后应该是一样的:
git clone https://github.com/fmtlib/fmt
cd fmt
git checkout 061e364b25b5e5ca7cf50dd25282892922375ddc
mkdir build
cmake ..
sudo make install
main2.cpp
#include <fmt/core.h>
#include <iostream>
int main()
std::cout << fmt::format(":x :#x \n", 16, 17, 18);
编译运行:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main2.out main2.cpp -lfmt
./main2.out
记录于:
https://en.cppreference.com/w/cpp/utility/format/format https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification更多信息请访问:std::string formatting like sprintf
C++20 之前的版本:干净地打印并将 std::cout
恢复到以前的状态
main.cpp
#include <iostream>
#include <string>
int main()
std::ios oldState(nullptr);
oldState.copyfmt(std::cout);
std::cout << std::hex;
std::cout << 16 << std::endl;
std::cout.copyfmt(oldState);
std::cout << 17 << std::endl;
编译运行:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
输出:
10
17
更多详情:Restore the state of std::cout after manipulating it
在 GCC 10.0.1、Ubuntu 20.04 上测试。
【讨论】:
如果有人想知道,您可以在en.cppreference.com/w/cpp/compiler_support 查看标准库支持的状态。此功能显示为“文本格式”。 @TylerKropp 漂亮的桌子,我不太清楚! std::format 不适用于最新的 gcc / clang - godbolt.org/z/33nP7G3qT【参考方案10】:你好吗!
#include <iostream>
#include <iomanip>
unsigned char arr[] = 4, 85, 250, 206;
for (const auto & elem : arr)
std::cout << std::setfill('0')
<< std::setw(2)
<< std::uppercase
<< std::hex
<< (0xFF & elem)
<< " ";
【讨论】:
以上是关于C++ cout 十六进制值?的主要内容,如果未能解决你的问题,请参考以下文章