どんな印刷符号なしcharとして六角レンチをc++で使用ostream?
-
21-08-2019 - |
質問
仕事をしたいとの符号なし8ビットの変数をC++.のいずれか unsigned char
または uint8_t
んどの演算がご関係が期待される、AFAIK uint8_t
ただのエイリアス unsigned char
, はこのようなもので、デバッガを示します。
問題は場を印刷して変数をostreamにはC++で扱うのに対して文字に置き換わります。している場合は:
unsigned char a = 0;
unsigned char b = 0xff;
cout << "a is " << hex << a <<"; b is " << hex << b << endl;
次に、この出力です:
a is ^@; b is 377
の代わりに
a is 0; b is ff
を使ってみました uint8_t
, が、先ほど述べたように、このtypedef投稿内容の投稿者に unsigned char
, でも同じようにします。たいのですがト変数"を確認してください。◆
編集: これは多くの場所でいます。そうすることで なし 鋳造 int
各時間がたい印刷?
解決
私は以下の技術を使用することをお勧めします:
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;
}
これを書くのは短いですが、元の溶液と同じ効率を持っており、それはあなたが「オリジナル」の文字出力を使用することを選択することができます。そしてそれは、タイプセーフなのです(「悪」のマクロを使用していない: - ))
他のヒント
使用します。
cout << "a is " << hex << (int) a <<"; b is " << hex << (int) b << endl;
そして、あなたはその後、先行ゼロでパディングをしたい場合:
#include <iomanip>
...
cout << "a is " << setw(2) << setfill('0') << hex << (int) a ;
私たちが使用していると、Cスタイルキャスト、なぜターミナルC ++悪さと全体の豚を移動して、マクロを使用しないで!
#define HEX( x )
setw(2) << setfill('0') << hex << (int)( x )
あなたが言うことができます。
cout << "a is " << HEX( a );
の編集のMartinStettnerのソリューションは非常に良くある、と語った。
!お問い合わせくださいこの時 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/.私のみ投稿ですることが明らかになってきており、著者は上記の予定はありません。
最もシンプルで、最も正しい技術な印刷を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);
読者のダイジェスト版はこの作品は、単項+オペレーターの力無opタイプ変換をintにおいて、正しくsignedness.そのため、unsigned charに変換するunsigned int、signed charに変換するint、charに変換するにはunsigned int intるかどうかによってcharが署名または符号なしプラットフォームで付属してい衝撃をするcharは特別な指定したいずれかの署名または符号なし).
にこの技術はできない場合があり明らかに何が起きているのか、人には馴染みのないます。しかし、私であると考えていることが分かりを使うことを想定していますことを保証するものではなく、教える他のいく何かが誤ったものよりすぐに明らかでない。
さて、これは私のために動作します:
std::cout << std::hex << (0xFF & a) << std::endl;
だから、このバイナリAND演算は、出力が0で満たされた左のビットを持つことになります保証し、また、符号なしに変換すること、その最上位ビットが1であれば、それは(int)
の左に1秒が追加される場合があります示唆したように、あなただけのa
をキャストした場合六角としてそれを印刷するCOUTを強制的にint型ます。
私はこのことができます願っています。
フム、昨日私は、ホイールを再発明したようだ...でもねえ、少なくともそれは:) char
sがそのように二桁の数字、4進数でshort
sとで印刷され、この時、一般的なホイールです。
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;
}
私はMartinStettnerのようにそれを行うが、桁数のための追加のパラメータを追加したい:
inline HexStruct hex(long n, int w=2)
{
return HexStruct(n, w);
}
// Rest of implementation is left as an exercise for the reader
ですから、デフォルトでは2桁の数字を持っていますが、4、8、または任意の場合は、あなたがしたいを設定することができます。
たとえばます。
int main()
{
short a = 3142;
std:cout << hex(a,4) << std::endl;
}
これはやり過ぎのように見えるかもしれませんが、Bjarneが言ったように:「ライブラリを書くのは簡単ではない、使いやすいべきである」
。私はTrungTNとアノンの答えは大丈夫だと思いますが、六角()関数を実装するMartinStettnerの方法は、六角<<(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;
}
これは、ストリーム演算子を実装するだけの価値があるではありません: - )
挑戦できますので、以下のコード:
unsigned char a = 0;
unsigned char b = 0xff;
cout << hex << "a is " << int(a) << "; b is " << int(b) << endl;
cout << hex
<< "a is " << setfill('0') << setw(2) << int(a)
<< "; b is " << setfill('0') << setw(2) << int(b)
<< endl;
cout << hex << uppercase
<< "a is " << setfill('0') << setw(2) << int(a)
<< "; b is " << setfill('0') << setw(2) << int(b)
<< endl;
出力:
a is 0; b is ff
a is 00; b is ff
a is 00; b is FF
Iは、Win32 / Linuxの(32/64ビット)で次のように使用します。
#include <iostream>
#include <iomanip>
template <typename T>
std::string HexToString(T uval)
{
std::stringstream ss;
ss << "0x" << std::setw(sizeof(uval) * 2) << std::setfill('0') << std::hex << +uval;
return ss.str();
}
今後の私の再開発版@FredOverflowます。私は以下のとおり異なる点がある。
問題の修正
- Rhsの
operator<<
きのconst
参考タイプです。に@FredOverflowのコードh.x >>= 4
出力変化h
, は、意外にも対応していない標準ライブラリは、タイプT
はrequaredするコピー-constructable. - とみ
CHAR_BITS
複数の4.@FredOverflowのコードはchar
8ビットは常にtrueになり、一部の実装にDsp、特にしているところも少なくなるchar
16ビットで、24-ビット、32ビット、等。
の向上:
- すべてのその他の標準ライブラリマニピュレータ値の種類など
std::uppercase
.でフォーマット出力を使用_print_byte
, 標準図書館マニピュレータもそのままご利用いただけます。 - 追加
hex_sep
印刷を別々のバイトがりますのでご注意くださいC/C++の"バイト"を定義収納ユニットのサイズchar
).追加のテンプレートパラメータSep
およびインスタンスを生成_Hex<T, false>
や_Hex<T, true>
にhex
やhex_sep
ます。 - を避けるバイナリコード膨張.機能
_print_byte
抽出したのoperator<<
, は、 機能パラメータsize
, のため、インスタンス生成のための異なるSize
.
以上のバイナリコード膨張:
どのように改善3、どんなに広く hex
や hex_sep
を使用、コピー(約)複製された機能了するバイナリコード: _print_byte<true>
や _print_byte<false>
.ということの重複も排除することと同じアプローチ:追加機能パラメータ sep
.ありがた場合を行うことにより、ランタイム if(sep)
が必要です。したい共通ライブラリユーティリティが広く使用されているプログラムした妥協の複製ではなく実行時のオーバーヘッド。いることをコンパイル時の if
:C++11 std::conditional
, のオーバーヘッドの呼び出しできれば最適化することによ inline
.
hex_print.h:
namespace Hex
{
typedef unsigned char Byte;
template <typename T, bool Sep> struct _Hex
{
_Hex(const T& t) : val(t)
{}
const T& val;
};
template <typename T, bool Sep>
std::ostream& operator<<(std::ostream& os, const _Hex<T, Sep>& h);
}
template <typename T> Hex::_Hex<T, false> hex(const T& x)
{ return Hex::_Hex<T, false>(x); }
template <typename T> Hex::_Hex<T, true> hex_sep(const T& x)
{ return Hex::_Hex<T, true>(x); }
#include "misc.tcc"
hex_print.tcc:
namespace Hex
{
struct Put_space {
static inline void run(std::ostream& os) { os << ' '; }
};
struct No_op {
static inline void run(std::ostream& os) {}
};
#if (CHAR_BIT & 3) // can use C++11 static_assert, but no real advantage here
#error "hex print utility need CHAR_BIT to be a multiple of 4"
#endif
static const size_t width = CHAR_BIT >> 2;
template <bool Sep>
std::ostream& _print_byte(std::ostream& os, const void* ptr, const size_t size)
{
using namespace std;
auto pbyte = reinterpret_cast<const Byte*>(ptr);
os << hex << setfill('0');
for (int i = size; --i >= 0; )
{
os << setw(width) << static_cast<short>(pbyte[i]);
conditional<Sep, Put_space, No_op>::type::run(os);
}
return os << setfill(' ') << dec;
}
template <typename T, bool Sep>
inline std::ostream& operator<<(std::ostream& os, const _Hex<T, Sep>& h)
{
return _print_byte<Sep>(os, &h.val, sizeof(T));
}
}
試験:
struct { int x; } output = {0xdeadbeef};
cout << hex_sep(output) << std::uppercase << hex(output) << endl;
出力:
de ad be ef DEADBEEF
私のことを義務付けられているが、そもトップのGoogleの検索結果のようなソリューションにも同様の問題が私の希望を任意の整数である六角文字列の変換内のテンプレートクラスです。私の目標であった Gtk::Entry
サブクラステンプレートを編集な整数値幅の六角レンチ、その傍らです。
この単項 operator+
トリックと std::make_unsigned
から <type_traits>
防止のための問題の拡大負 int8_t
または signed char
値が発生するもの この答え
とにかくすると思いますより簡潔で、他の汎用溶液とする。もう 他の 署名または符号なし整数型、捨てコンパイル時にエラーしようとするとインスタンスを生成する機能を任意の整数と種類です。
template <
typename T,
typename = typename std::enable_if<std::is_integral<T>::value, T>::type
>
std::string toHexString(const T v)
{
std::ostringstream oss;
oss << std::hex << +((typename std::make_unsigned<T>::type)v);
return oss.str();
}
一部の使用例:
int main(int argc, char**argv)
{
int16_t val;
// Prints 'ff' instead of "ffffffff". Unlike the other answer using the '+'
// operator to extend sizeof(char) int types to int/unsigned int
std::cout << toHexString(int8_t(-1)) << std::endl;
// Works with any integer type
std::cout << toHexString(int16_t(0xCAFE)) << std::endl;
// You can use setw and setfill with strings too -OR-
// the toHexString could easily have parameters added to do that.
std::cout << std::setw(8) << std::setfill('0') <<
toHexString(int(100)) << std::endl;
return 0;
}
更新: さくなければなりません。んとうに ostringstream
使用を組み合わせることができ、孔、単項演算子トリックの受け答えの構造体に基づく液に以下のような人材を求めます。ご注意ここでは、私を変更したテンプレートを削除し、チェックのための整数です。の make_unsigned
利用が十分にコンパイル時の型安全保及び保証による
template <typename T>
struct HexValue
{
T value;
HexValue(T _v) : value(_v) { }
};
template <typename T>
inline std::ostream& operator<<(std::ostream& o, const HexValue<T>& hs)
{
return o << std::hex << +((typename std::make_unsigned<T>::type) hs.value);
}
template <typename T>
const HexValue<T> toHex(const T val)
{
return HexValue<T>(val);
}
// Usage:
std::cout << toHex(int8_t(-1)) << std::endl;
これも動作します:
std::ostream& operator<< (std::ostream& o, unsigned char c)
{
return o<<(int)c;
}
int main()
{
unsigned char a = 06;
unsigned char b = 0xff;
std::cout << "a is " << std::hex << a <<"; b is " << std::hex << b << std::endl;
return 0;
}
私はこの方法で使用しています。
char strInput[] = "yourchardata";
char chHex[2] = "";
int nLength = strlen(strInput);
char* chResut = new char[(nLength*2) + 1];
memset(chResut, 0, (nLength*2) + 1);
for (int i = 0; i < nLength; i++)
{
sprintf(chHex, "%02X", strInput[i]& 0x00FF);
memcpy(&(chResut[i*2]), chHex, 2);
}
printf("\n%s",chResut);
delete chResut;
chResut = NULL;