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 &lt;&lt; hex &lt;&lt; a &lt;&lt; dec; 之类的内容将其改回。 @ShreevatsaR 通过十六进制恢复 dec 的一个问题是 dec 可能不是之前设置的值,尤其是在您编写通用库方法时。 This question 有一些关于如何存储和恢复状态的答案。您可以使用ios::fmtflags f(cout.flags()); 保存状态并使用out.flags(f); 恢复它。 然后通过std::cout.flags(f);恢复【参考方案2】:

std::hex 定义在&lt;ios&gt; 中,它包含在&lt;iostream&gt; 中。但是要使用 std::setprecision/std::setw/std::setfill/etc 之类的东西,您必须包含 &lt;iomanip&gt;

【讨论】:

【参考方案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::uppercasestd::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 十六进制值?的主要内容,如果未能解决你的问题,请参考以下文章

C++中cin、cout的一些特殊用法

C++中cout的格式使用

C++中cout的格式使用

C++中cout的格式使用

C++中cout的格式使用

在 C++ 中转储十六进制浮点数