Nat*_*man 68 c++ formatting ostream
我想在C++中使用无符号的8位变量.关于算术的任何一个unsigned char或者uint8_t做的伎俩(这是预期的,因为AFAIK uint8_t只是一个别名unsigned char,或者调试器提出它.
问题是,如果我在C++中使用ostream打印出变量,它会将其视为char.如果我有:
unsigned char a = 0;
unsigned char b = 0xff;
cout << "a is " << hex << a <<"; b is " << hex << b << endl;
Run Code Online (Sandbox Code Playgroud)
然后输出是:
a is ^@; b is 377
Run Code Online (Sandbox Code Playgroud)
代替
a is 0; b is ff
Run Code Online (Sandbox Code Playgroud)
我尝试过使用uint8_t,但正如我之前提到的,那是typedef'ed unsigned char,所以它也是如此.如何正确打印变量?
编辑:我在我的代码中的许多地方都这样做.有没有什么办法可以做到这一点,而不铸造int我想打印每一次?
Mar*_*ner 51
我建议使用以下技术:
struct HexCharStruct
{
unsigned char c;
HexCharStruct(unsigned char _c) : c(_c) { }
};
inline std::ostream& operator<<(std::ostream& o, const HexCharStruct& hs)
{
return (o << std::hex << (int)hs.c);
}
inline HexCharStruct hex(unsigned char _c)
{
return HexCharStruct(_c);
}
int main()
{
char a = 131;
std::cout << hex(a) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
它的编写时间短,与原始解决方案具有相同的效率,它允许您选择使用"原始"字符输出.它是类型安全的(不使用"邪恶"宏:-))
小智 47
使用:
cout << "a is " << hex << (int) a <<"; b is " << hex << (int) b << endl;
Run Code Online (Sandbox Code Playgroud)
如果你想要用前导零填充,那么:
#include <iomanip>
...
cout << "a is " << setw(2) << setfill('0') << hex << (int) a ;
Run Code Online (Sandbox Code Playgroud)
由于我们正在使用C风格的演员阵容,为什么不用终端C++的糟糕程度来使用一个宏!
#define HEX( x )
setw(2) << setfill('0') << hex << (int)( x )
Run Code Online (Sandbox Code Playgroud)
你可以说
cout << "a is " << HEX( a );
Run Code Online (Sandbox Code Playgroud)
编辑:话虽如此,MartinStettner的解决方案更好!
ltc*_*ltc 31
您可以在http://cpp.indi.frih.net/blog/2014/09/tippet-printing-numeric-values-for-chars-and-uint8_t/和http://cpp.indi上阅读更多相关信息. frih.net/blog/2014/08/code-critique-stack-overflow-posters-cant-print-the-numeric-value-of-a-char/.我只发布这个,因为很明显上述文章的作者并不打算这样做.
最简单,最正确的技术是将字符串打印为十六进制
unsigned char a = 0;
unsigned char b = 0xff;
auto flags = cout.flags(); //I only include resetting the ioflags because so
//many answers on this page call functions where
//flags are changed and leave no way to
//return them to the state they were in before
//the function call
cout << "a is " << hex << +a <<"; b is " << +b << endl;
cout.flags(flags);
Run Code Online (Sandbox Code Playgroud)
读者摘要版本的工作原理是一元+运算符强制将no op类型转换为具有正确签名的int.因此,unsigned char转换为unsigned int,signed char转换为int,char将转换为unsigned int或int,具体取决于char是否在您的平台上签名或签名(对于很多char来说,这是特别令人震惊的并且未指定为有符号或无符号).
这种技术的唯一不利之处在于,对于不熟悉它的人来说可能并不明显.但是,我认为最好使用正确的技术并教导其他人,而不是做一些不正确但更直接清楚的事情.
vit*_*aut 17
在 C++20 中,您将能够使用它std::format来执行此操作:
std::cout << std::format("a is {:x}; b is {:x}\n", a, b);
Run Code Online (Sandbox Code Playgroud)
输出:
std::cout << std::format("a is {:x}; b is {:x}\n", a, b);
Run Code Online (Sandbox Code Playgroud)
在此期间,您可以使用的{} FMT库,std::format是基于。{fmt} 还提供了print使这更容易和更高效的功能(Godbolt):
fmt::print("a is {:x}; b is {:x}\n", a, b);
Run Code Online (Sandbox Code Playgroud)
免责声明:我是 {fmt} 和 C++20 的作者std::format。
好吧,这对我有用:
std::cout << std::hex << (0xFF & a) << std::endl;
Run Code Online (Sandbox Code Playgroud)
如果(int)按照建议的方式a进行强制转换,则它的最高有效位为1时,可能会在其左侧添加1。因此,执行此二进制AND操作可确保输出的左侧位由0填充,并将其转换为unsigned int,从而强制cout打印它作为十六进制。
我希望这有帮助。
我认为TrungTN和anon的答案还可以,但是MartinStettner实现hex()函数的方法并不是很简单,而且太黑暗了,考虑到hex << (int)mychar已经是一种解决方法。
这是我的解决方案,使“<<”运算符更容易:
#include <sstream>
#include <iomanip>
string uchar2hex(unsigned char inchar)
{
ostringstream oss (ostringstream::out);
oss << setw(2) << setfill('0') << hex << (int)(inchar);
return oss.str();
}
int main()
{
unsigned char a = 131;
std::cout << uchar2hex(a) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
只是不值得实现流运算符:-)
嗯,看来我昨天重新发明了轮子……但是,至少这次是通用轮子了:)chars印有两个十六进制数字,shorts 印有四个十六进制数字,依此类推。
template<typename T>
struct hex_t
{
T x;
};
template<typename T>
hex_t<T> hex(T x)
{
hex_t<T> h = {x};
return h;
}
template<typename T>
std::ostream& operator<<(std::ostream& os, hex_t<T> h)
{
char buffer[2 * sizeof(T)];
for (auto i = sizeof buffer; i--; )
{
buffer[i] = "0123456789ABCDEF"[h.x & 15];
h.x >>= 4;
}
os.write(buffer, sizeof buffer);
return os;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
114065 次 |
| 最近记录: |