Wie kann ich 0x0a anstelle von 0xa mit cout drucken?
#include <iostream>
using std::cout;
using std::endl;
using std::hex;
int main()
{
cout << hex << showbase << 10 << endl;
}
Wie kann ich 0x0a anstelle von 0xa mit cout drucken?
#include <iostream>
using std::cout;
using std::endl;
using std::hex;
int main()
{
cout << hex << showbase << 10 << endl;
}
Das funktioniert bei mir im GCC:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << "0x" << setfill('0') << setw(2) << right << hex << 10 << endl;
}
Wenn Sie die Formatierungswut von iostream satt haben, geben Sie Boost.Format einen Versuch. Es erlaubt gute altmodische, printf-ähnliche Formatspezifikationen und ist dennoch typsicher.
#include <iostream>
#include <boost/format.hpp>
int main()
{
std::cout << boost::format("0x%02x\n") % 10;
}
UPDATE (2019)
Überprüfen Sie die Bibliothek {fmt} das akzeptiert wurde in C++20 . Benchmarks zeigen, dass es schneller als Boost.Format ist.
#if __has_include(<format>)
#include <format>
using std::format;
#else
#include <fmt/format.h>
using fmt::format;
#endif
std::cout << format("{:#04x}\n", 10);
Diese Antwort ist falsch. Wenn jemand cout << left << whatever
erhalten Sie aufgrund der anhaltenden Links/Rechts-Verschiebung eine schlechte Ausgabe. Es sollte sein setfill('0') << setw(2) << right << hex
um stets die richtige Ausrichtung zu gewährleisten.
@fuujuhi Falsch ? Das ist ziemlich hart. Ich würde sagen, dass es unvollständig ist. Aber danke für die Anregung.
@EmileCornier Entschuldigung, ich wollte nicht zu hart sein. In der Tat, unvollständig, aber leider kann zu bösen Bugs führen. Ich hatte in letzter Zeit zwei Bugs in meinem Code aufgrund von hartnäckigem iomanip (um ganz ehrlich zu sein: ich habe früher viel in C++ programmiert, aber jetzt nicht mehr), und das hat mich zu der Überzeugung gebracht, dass C++ iostream furchtbar falsch ist. Für eine moderne Sprache macht iostream das Drucken der einfachsten Dinge zu einem kompletten Albtraum. Man denkt, man druckt einen Integer, aber in Wirklichkeit druckt man ihn in Hex. Oder man bekommt "0x90" in der Ausgabe, aber in Wirklichkeit ist der Wert 0x09.
Utilice setw y setfill von iomanip
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
using std::hex;
int main()
{
cout << "0x" << std::setfill('0') << std::setw(2) << hex << 10 << endl;
}
Mich persönlich stört der zustandsbehaftete Charakter von iostreams immer. Ich denke, das Boost-Format ist eine bessere Option, daher würde ich die andere Antwort empfehlen.
Ich bekomme auch 0xA. Warum ist es so verdammt schwer, iostream dazu zu bringen, Dinge so zu formatieren, wie man es möchte?
Das hat bei mir funktioniert: cout << "0x" << setfill('0') << setw(2) << hex << 10 << endl
@Doug T.: Ich habe mir die Freiheit genommen, Ihre Antwort zu bearbeiten, damit der Auftraggeber sie als die richtige Antwort akzeptieren kann.
Wenn Sie eine einfachere Möglichkeit zur Ausgabe einer Hexadezimalzahl suchen, könnten Sie eine Funktion wie die folgende schreiben:
Die aktualisierte Version wird unten dargestellt; es gibt zwei Möglichkeiten, die 0x
Basisindikator eingefügt werden, mit Fußnoten, die die Unterschiede zwischen ihnen erläutern. Die ursprüngliche Version wird am Ende der Antwort beibehalten, um niemanden zu belästigen, der sie verwendet hat.
Beachten Sie, dass sowohl die aktualisierte als auch die ursprüngliche Version für Systeme, bei denen die Bytegröße ein Vielfaches von 9 Bit ist, möglicherweise etwas angepasst werden muss.
#include <type_traits> // For integral_constant, is_same.
#include <string> // For string.
#include <sstream> // For stringstream.
#include <ios> // For hex, internal, [optional] showbase.
// Note: <ios> is unnecessary if <iostream> is also included.
#include <iomanip> // For setfill, setw.
#include <climits> // For CHAR_BIT.
namespace detail {
constexpr int HEX_DIGIT_BITS = 4;
//constexpr int HEX_BASE_CHARS = 2; // Optional. See footnote #2.
// Replaced CharCheck with a much simpler trait.
template<typename T> struct is_char
: std::integral_constant<bool,
std::is_same<T, char>::value ||
std::is_same<T, signed char>::value ||
std::is_same<T, unsigned char>::value> {};
}
template<typename T>
std::string hex_out_s(T val) {
using namespace detail;
std::stringstream sformatter;
sformatter << std::hex
<< std::internal
<< "0x" // See footnote #1.
<< std::setfill('0')
<< std::setw(sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) // See footnote #2.
<< (is_char<T>::value ? static_cast<int>(val) : val);
return sformatter.str();
}
Sie kann wie folgt verwendet werden:
uint32_t hexU32 = 0x0f;
int hexI = 0x3c;
unsigned short hexUS = 0x12;
std::cout << "uint32_t: " << hex_out_s(hexU32) << '\n'
<< "int: " << hex_out_s(hexI) << '\n'
<< "unsigned short: " << hex_out_s(hexUS) << std::endl;
Sehen Sie sich beide Optionen (wie in den Fußnoten unten beschrieben) live an: aquí .
Fußnoten:
Diese Zeile ist für die Darstellung der Basis verantwortlich und kann eine der folgenden sein:
<< "0x"
<< std::showbase
Die erste Option wird bei benutzerdefinierten Typen, die versuchen, negative Hex-Zahlen auszugeben, nicht korrekt angezeigt -0x##
statt als <complement of 0x##>
wobei das Vorzeichen nach der Basis angezeigt wird (wie 0x-##
) und nicht vor ihm. Dies ist sehr selten ein Problem, so dass ich persönlich diese Option bevorzuge.
Wenn dies ein Problem ist, können Sie bei Verwendung dieser Typen vor der Ausgabe der Basis auf Negativität prüfen und dann mit abs()
(o ein Brauch abs()
die einen Wert ohne Vorzeichen zurückgibt wenn Sie in der Lage sein müssen, die höchstnegativen Werte in einem 2er-Komplement-System zu verarbeiten) auf val
.
Bei der zweiten Option wird die Basis weggelassen, wenn val == 0
und zeigt (z. B. für int
, donde int
ist 32 Bit) 0000000000
statt der erwarteten 0x00000000
. Dies ist zurückzuführen auf die showbase
Flagge, die behandelt wird wie printf()
's #
Modifikator intern.
Wenn dies ein Problem ist, können Sie prüfen, ob val == 0
und wenden Sie in diesem Fall eine Sonderbehandlung an.
Je nachdem, welche Option für die Darstellung der Basis gewählt wurde, müssen zwei Zeilen geändert werden.
<< "0x"
entonces HEX_BASE_CHARS
ist unnötig und kann weggelassen werden.Bei Verwendung von << std::showbase
dann wird der Wert, der an setw()
muss diesem Umstand Rechnung tragen:
<< std::setw((sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) + HEX_BASE_CHARS)
Die ursprüngliche Fassung lautet wie folgt:
// Helper structs and constants for hex_out_s().
namespace hex_out_helper {
constexpr int HEX_DIGIT_BITS = 4; // One hex digit = 4 bits.
constexpr int HEX_BASE_CHARS = 2; // For the "0x".
template<typename T> struct CharCheck {
using type = T;
};
template<> struct CharCheck<signed char> {
using type = char;
};
template<> struct CharCheck<unsigned char> {
using type = char;
};
template<typename T> using CharChecker = typename CharCheck<T>::type;
} // namespace hex_out_helper
template<typename T> std::string hex_out_s(T val) {
using namespace hex_out_helper;
std::stringstream sformatter;
sformatter << std::hex
<< std::internal
<< std::showbase
<< std::setfill('0')
<< std::setw((sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) + HEX_BASE_CHARS)
<< (std::is_same<CharChecker<T>, char>{} ? static_cast<int>(val) : val);
return sformatter.str();
}
Diese kann dann wie folgt verwendet werden:
uint32_t hexU32 = 0x0f;
int hexI = 0x3c;
unsigned short hexUS = 0x12;
std::cout << hex_out_s(hexU32) << std::endl;
std::cout << hex_out_s(hexI) << std::endl;
std::cout << "And let's not forget " << hex_out_s(hexUS) << std::endl;
Arbeitsbeispiel: aquí .
std::internal
! Du hast den großen Preis gewonnen! Das hat mir noch gefehlt! Vielen Dank @Justin Time.
@fljx Gern geschehen. Ich habe es verbessert, seit ich diese Antwort gepostet habe, also werde ich die Antwort bearbeiten, um dies zu berücksichtigen.
Soweit ich weiß, sollten die erforderlichen Includes irgendwo aufgeführt sein: climits
, iomanip
, iostream
, types
, string
, stringstream
mit Klimazonen für CHAR_BIT
die mich dazu gebracht hat, diesen Kommentar zu schreiben.
In C++20 werden Sie in der Lage sein, Folgendes zu verwenden std::format
um dies zu tun:
std::cout << std::format("{:02x}\n", 10);
出力します。
0a
In der Zwischenzeit können Sie die {fmt}-Bibliothek , std::format
basiert auf. {fmt} bietet auch die print
Funktion, die dies noch einfacher und effizienter macht ( godbolt ):
fmt::print("{:02x}\n", 10);
Haftungsausschluss : Ich bin der Autor von {fmt} und C++20 std::format
.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
0 Stimmen
Was genau sind Ihre Anforderungen? Der Titel sagt
0x0a
heißt es im Text Ihrer Frage0x0A
. In jedem Fall ist eine explizitestd::cout << "0x0a"
ostd::cout << "0x0A"
scheint Ihren Anforderungen zu entsprechen, aber ich nehme an, dass Sie wirklich eine Zahl formatieren wollen. Wie wollen Sie (z. B.) 16, 255, 256, 65536, -1 formatiert haben?0 Stimmen
@Charles Die Frage bezog sich darauf, wie man die 0 nach dem x und vor dem A bzw. dem a druckt. Wie Sie sehen können, ist die erste Antwort falsch, da sie immer noch 0xa druckt (0xA, wenn Großbuchstaben verwendet werden). Aber wie auch immer, die Frage ist bereits als beantwortet markiert.
0 Stimmen
Aber warum die zusätzliche
0
? Wollen Sie immer0x0
oder benötigen Sie eine Mindestlänge für die Zeichenfolge?0 Stimmen
Wenn die Hexadezimalzahl 0xA ist, möchte ich sie 0x0A. Wenn die Zahl 0x123 ist, möchte ich sie 0x0123 usw., d. h. eine gerade Anzahl von Hex-Ziffern.
0 Stimmen
Ich glaube, Sie haben nicht verstanden, worauf ich hinaus will. Sie haben genau angegeben, wie 10 erscheinen soll, aber was ist mit 1 bis 9 und 11 bis 15? Was ist mit 256? Wollen Sie
0x0a
weil Sie eine Mindestbreite wollen oder weil Sie immer eine führende Null wollen? Wenn Sie Ihre Angaben nicht genau machen, erhalten Sie möglicherweise nicht die gewünschten Antworten.0 Stimmen
Mögliche Duplikate von Wie kann ich einen int mit führenden Nullen auffüllen, wenn ich den Operator cout << verwende?