web-dev-qa-db-fra.com

Comment puis-je imprimer 0x0a au lieu de 0xa en utilisant cout?

Comment puis-je imprimer 0x0a au lieu de 0xa avec cout?

#include  <iostream>

using std::cout;  
using std::endl;  
using std::hex;

int main()  
{  
    cout << hex << showbase << 10 << endl;  
}
46
Ayrosa

Cela fonctionne pour moi dans GCC:

#include  <iostream>
#include  <iomanip>

using namespace std;

int main()
{
    cout << "0x" << setfill('0') << setw(2) << hex << 10 << endl;
}

Si vous en avez assez de l'exagération du formatage d'iostream, essayez Boost.Format a try. Il autorise les spécificateurs de format de style printf à l'ancienne, tout en restant sûr pour le type.

#include <iostream>
#include <boost/format.hpp>

int main()
{
    std::cout << boost::format("0x%02x\n") % 10;
}
75
Emile Cormier

Utilisez setw et setfill from 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;
}

Personnellement, la nature dynamique de iostreams me gêne toujours. Je pense que le format boost est une meilleure option, alors j’avais recommandé l’autre réponse. 

16
Doug T.

Si vous voulez créer un moyen plus facile de générer un nombre hexadécimal, vous pouvez écrire une fonction comme celle-ci:

La version mise à jour est présentée ci-dessous; L’indicateur 0x base peut être inséré de deux manières différentes, avec des notes de bas de page détaillant les différences entre elles. La version originale est conservée au bas de la réponse, afin de ne pas gêner ceux qui l'utilisaient.

Notez que les versions mises à jour et originales peuvent nécessiter une adaptation pour les systèmes où la taille en octets est un multiple de 9 bits.

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();
}

Il peut être utilisé comme suit:

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;

Voir les deux options (comme indiqué dans les notes ci-dessous) en direct: ici .

Notes de bas de page:

  1. Cette ligne est responsable de l'affichage de la base et peut être l'une des suivantes:

    << "0x"
    << std::showbase
    
    • La première option ne s'affichera pas correctement pour les types personnalisés qui essaient de générer des nombres hexadécimaux négatifs sous la forme -0x## au lieu de <complement of 0x##>, le signe étant affiché après la base (sous la forme 0x-##). Ceci est très rarement un problème, donc je préfère personnellement cette option.

      S'il s'agit d'un problème, vous pouvez vérifier la négativité avant d'utiliser la base lorsque vous utilisez ces types, puis utilisez abs() (ou un abs() personnalisé qui renvoie une valeur non signée , si vous devez pouvoir gérer le - valeurs négatives sur un système de complément à 2) sur val.

    • La deuxième option omettra la base lorsque val == 0, affichant (par exemple, pour int, où int est 32 bits) 0000000000 au lieu du 0x00000000 attendu. Cela est dû au fait que l'indicateur showbase est traité en interne comme le modificateur # de printf().

      S'il s'agit d'un problème, vous pouvez vérifier si val == 0 et appliquer un traitement spécial le cas échéant.

  2. En fonction de l'option choisie pour afficher la base, deux lignes devront être modifiées.

    • Si vous utilisez << "0x", alors HEX_BASE_CHARS est inutile et peut être omis.
    • Si vous utilisez << std::showbase, la valeur fournie à setw() doit en tenir compte:

      << std::setw((sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) + HEX_BASE_CHARS)
      

La version originale est la suivante:

// 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();
}

Ce qui peut alors être utilisé comme ceci:

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;

Exemple de travail: ici .

7
Justin Time

La chose importante qui manque à la réponse est que vous devez utiliser right avec tous les drapeaux mentionnés ci-dessus:

cout<<"0x"<<hex<<setfill('0')<<setw(2)<<right<<10;
1
lentz

Pour raccourcir les choses pour la sortie hex, j'ai fait une macro simple

#define PADHEX(width, val) setfill('0') << setw(width) << std::hex << (unsigned)val

puis

cout << "0x" << PADHEX(2, num) << endl;
1
rwhenderson

Imprimez n'importe quel nombre en hexadécimal avec le remplissage automatique '0' ou définissez Le modèle permet n’importe quel type de données (par exemple, uint8_t)

template<typename T, typename baseT=uint32_t> struct tohex_t {
    T num_;
    uint32_t width_;
    bool showbase_;

    tohex_t(T num, bool showbase = false, uint32_t width = 0) { num_ = num; showbase_ = showbase; width_ = width; }
    friend std::ostream& operator<< (std::ostream& stream, const tohex_t& num) {
        uint32_t w;
        baseT val;

        if (num.showbase_)
            stream << "0x";

        if (num.width_ == 0) {
            w = 0;
            val = static_cast<baseT>(num.num_);
            do { w += 2; val = val >> 8; } while (val > 0);
        }
        else {
            w = num.width_;
        }
        stream << std::hex << std::setfill('0') << std::setw(w) << static_cast<baseT>(num.num_);

        return stream;
    }
};
template<typename T> tohex_t<T> TO_HEX(T const &num, bool showbase = false, uint32_t width = 0) { return tohex_t<T>(num, showbase, width); }

Exemple:

std::stringstream sstr;
uint8_t ch = 91;
sstr << TO_HEX(5) << ',' << TO_HEX(ch) << ',' << TO_HEX('0') << std::endl;
sstr << TO_HEX(1, true, 4) << ',' << TO_HEX(15) << ',' << TO_HEX(-1) << ',';
sstr << TO_HEX(513) << ',' << TO_HEX((1 << 16) + 3, true);
std::cout << sstr.str();

Sortie:

05,5b,30
0x0001,0f,ffffffff,0201,0x010003
0
Danilo Ramos

essayez ceci .. vous ajoutez simplement des zéros en fonction de la magnitude.

cout << hex << "0x" << ((c<16)?"0":"") << (static_cast<unsigned int>(c) & 0xFF) << "h" << endl;

Vous pouvez facilement modifier cela pour travailler avec des nombres plus importants.

cout << hex << "0x";
cout << ((c<16)?"0":"") << ((c<256)?"0":"");
cout << (static_cast<unsigned int>(c) & 0xFFF) << "h" << endl;

Le facteur est 16 (pour un chiffre hexadécimal):
16, 256, 4096, 65536, 1048576, ..
respectif
0x10, 0x100, 0x1000, 0x10000, 0x100000, ..

Par conséquent, vous pouvez aussi écrire comme ça.

cout << hex << "0x" << ((c<0x10)?"0":"") << ((c<0x100)?"0":"") << ((c<0x1000)?"0":"") << (static_cast<unsigned int>(c) & 0xFFFF) << "h" << endl;

Et ainsi de suite ..: P

0
Michael Grieswald