在C++中将十六进制值打印到控制台
Printing hexadecimal values to console in C++
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
char array[10];
for(int i = 0; i<10;i++)
{
array[i] = 'a' + i;
}
char* test = array;
printf("%xn", test);
cout << hex << test << endl;
}
此输出为:
bffff94e
abcdefghijN???
为什么它不打印同样的东西?
cout << hex << test << endl;
它打印字符串,而不是地址。这是因为存在operator<<
的重载,它将char const*
作为参数,并且此重载将参数视为字符串。
如果要打印地址,请将参数转换为 void*
,以便调用其他重载operator<<
来打印地址。
cout << hex << static_cast<void*>(test) << endl;
将以十六进制格式打印地址。
请注意,这里不需要hex
流操纵器,因为地址将以十六进制格式打印。所以
cout << static_cast<void*>(test) << endl;
就够了。
因为您的程序具有未定义的行为。 因为你要求它打印不同的东西。
您调用printf
是非法的,会导致未定义行为(并且是为什么永远不应该使用printf
的一个很好的例子)。您的格式说明符说unsigned int
要从参数列表,并以十六进制输出。 传递它除了任何东西unsigned int
是未定义的行为。 碰巧,给定的方式varargs 通常是实现的,如果你在一台机器上 unsigned
s 和指针的大小相同,您可能会输出指针的值,将其位视为unsigned
。但是,其他行为当然是可能的。 (如果我没记错的话,G++ 会警告这个结构;也有可能在某些平台,它会崩溃。
在std::cout
的情况下,你已经过去了char*
。 根据定义,char*
被视为"\0"字符串,而不是指针(和当然不是作为unsigned int
)。 再一次,你没有定义行为,因为您的char*
不指向以"\0"结尾的字符串;你永远不会在末尾加上"\0"。 (这可能解释了"N???"
您会在输出的末尾看到。 但同样,未定义的行为是,好吧,未定义。 代码可能很容易崩溃。
最后,您同时使用了printf
和std::cout
;结果不是真正指定,除非您在两者之间刷新流。(实际上,如果您要输出到交互式设备,则刷新应在输出'n'
字符时发生。 如果重定向但是,输出到文件可能会得到不同的东西。
不清楚你想要什么。 如果要输出地址 array
,它将是:
printf( "%pn", test );
std::cout << static_cast<void*>( test ) << std::endl;
如果要输出生成的字符串,请将"\0"附加到它的末尾(不溢出缓冲区),然后:
printf( "%sn", test );
std::cout << test << std::endl;
我不确定你想做什么"十六进制";没有这样的东西字符串的十六进制表示形式,指针的表示形式为已定义实现,并且不需要考虑任何在 IOstream 中格式化参数。 (通常,在大多数现代机器上,它将是十六进制。 但是我已经在很多地方工作过八进制,至少一个不仅仅是一个数字,无论的基地。 如果你想要一个十六进制转储 array
,你必须循环,将每个值输出为十六进制unsigned
:
for ( int i = 0; i < 10; ++ i ) {
printf( "%x", static_cast<unsigned char>( test[i] ) );
}
printf( "n" );
std::cout.setf( std::ios_base::hex, std::ios::basefield );
for ( int i = 0; i < 10; ++ i ) {
std::cout << static_cast<unsigned>( static_cast<unsigned char>( test[i] ) );
}
std::cout.setf( std::ios_base::dec, std::ios::basefield );
std::cout << std::endl;
最后:关于演员表的一句话:普通char
可以签名或无符号;如果已签名,则将其转换为int
或 unsigned
,可能会产生负值(int
)或非常大正值 ( unsigned
)。 因此,第一次转换为 unsigned char
,这保证了[0, UINT_MAX]
范围内的结果。其次,当然,我们必须将unsigned char
转换为unsigned
:
在
printf
的情况下,因为否则我们将有未定义行为,但转换是隐式的,因为将unsigned char
作为 vararg 传递会自动将其提升为unsigned
;和在
std::cout
的情况下,因为规则是任何字符类型输出为字符,而不是数值(并且由于类型在函数重载解析中使用,而不是传递给 vararg 或unsigned
,没有隐式转换)。
test
本身就是一个指针,即它存储一个地址。printf
语句打印该地址的十六进制值。
然后,cout <<
语句打印整个字符串,因为std::hex
操纵器不会影响字符串的打印方式。它仅影响整数的打印方式。
你能做的是
- 循环遍历数组的字符
- 将每个转换为整数并使用
std::hex
操纵器打印
那看起来像这样:
for (int i = 0 ; i < 10 ; ++i)
std::cout << std::hex << static_cast<int>(array[i]) << 'n';
cout << HEX <<
不能用于字符*来打印十六进制字符字符串,但是您可以将其用于整数,双精度,浮点数等。
而且,当你第二次打印时,为什么字符串有一些乱码,因为你没有给字符串的""表示字符串的结尾
- c ++控制台应用程序,如何在控制台外部打印字符
- 控制台打印时间功能产生1
- 如何通过按 F2 或 F3 等键使控制台打印某些内容
- cout 不打印任何内容到控制台
- 如何在 C++ 中将 U32 字符串和 U16string 打印到控制台
- 打印到文件和控制台 C++
- 在 c++ 中打印到控制台的最佳方式是什么?
- 我的控制台正在打印随机单词以及没有执行正确的数学运算
- C++控制台打印在同一行上,带回车符
- 硬编码字符串与强制转换为 PUCHAR 并打印到控制台时从控制台读取的字符串的结果不同
- V8 控制台.log不打印
- 使用 C++ shell 为 C++ 中的 2 D 动态数组赋值,控制台不会打印出任何内容
- cURL 保持打印传输到控制台?
- SDL 未打印到控制台
- qDebug() 在升级到 ubuntu 17.10(和 Fedora)后停止工作(不再打印到控制台)
- 使用具有 UTF8 编码的源文件将 UTF8 符号打印到 Windows 控制台
- 如何在 ATL COM 模块中打印控制台输出
- 打印到控制台或字符串/流
- Cout 无法在显示器上打印(控制台)
- 禁止从导入的 DLL 打印控制台