首页 文章

C中的十六进制字符串的整数

提问于
浏览 1965 次
93

如何在C++中将整数转换为十六进制字符串?

我可以找到一些方法来做到这一点,但它们似乎主要针对C语言 . 它不是用C语言做的本地方式 . 这是一个非常简单的问题;我有一个 int ,我想将其转换为十六进制字符串以便以后打印 .

14 回答

  • 162

    使用 <iomanip>std::hex . 如果你打印,只需发送到 std::cout ,如果没有,然后使用std::stringstream

    std::stringstream stream;
    stream << std::hex << your_int;
    std::string result( stream.str() );
    

    如果您愿意,可以在 << "0x" 之前添加 << 或其他任何内容 .

    其他感兴趣的是#674410_(八进制)和 std::dec (回到十进制) .

    您可能遇到的一个问题是,这会产生表示它所需的确切数字位数 . 您可以使用 setfillsetw 来解决问题:

    stream << std::setfill ('0') << std::setw(sizeof(your_type)*2) 
           << std::hex << your_int;
    

    最后,我建议这样一个功能:

    template< typename T >
    std::string int_to_hex( T i )
    {
      std::stringstream stream;
      stream << "0x" 
             << std::setfill ('0') << std::setw(sizeof(T)*2) 
             << std::hex << i;
      return stream.str();
    }
    
  • 2

    为了使它更轻更快,我建议使用直接填充字符串 .

    template <typename I> std::string n2hexstr(I w, size_t hex_len = sizeof(I)<<1) {
        static const char* digits = "0123456789ABCDEF";
        std::string rc(hex_len,'0');
        for (size_t i=0, j=(hex_len-1)*4 ; i<hex_len; ++i,j-=4)
            rc[i] = digits[(w>>j) & 0x0f];
        return rc;
    }
    
  • 2

    使用 std::stringstream 将整数转换为字符串及其特殊操纵符来设置基数 . 例如:

    std::stringstream sstream;
    sstream << std::hex << my_integer;
    std::string result = sstream.str();
    
  • 1

    只需将其打印为十六进制数:

    int i = /* ... */;
    std::cout << std::hex << i;
    
  • 28

    您可以尝试以下方法 . 它的工作......

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <sstream>
    using namespace std;
    
    template <class T>
    string to_string(T t, ios_base & (*f)(ios_base&))
    {
      ostringstream oss;
      oss << f << t;
      return oss.str();
    }
    
    int main ()
    {
      cout<<to_string<long>(123456, hex)<<endl;
      system("PAUSE");
      return 0;
    }
    
  • 4
    int num = 30;
    std::cout << std::hex << num << endl; // This should give you hexa- decimal of 30
    
  • 8

    对于那些想出很多/大多数 ios::fmtflags 不能与 std::stringstream 一起使用但又像Kornel发布的模板想法的人一样,以下工作并且相对干净:

    #include <iomanip>
    #include <sstream>
    
    
    template< typename T >
    std::string hexify(T i)
    {
        std::stringbuf buf;
        std::ostream os(&buf);
    
    
        os << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2)
           << std::hex << i;
    
        return buf.str().c_str();
    }
    
    
    int someNumber = 314159265;
    std::string hexified = hexify< int >(someNumber);
    
  • 2

    看看我的解决方案,[1]我从我的项目中逐字复制,因此包含德语是API文档 . 我的目标是在我的实际需求中结合灵活性和安全性:[2]

    • no 0x prefix 补充:来电者可以决定

    • 自动 width deduction :少打字

    • explicit width 控制:加宽格式化,(无损)缩小以节省空间

    • 能够处理 long long

    • 仅限于 integral types :通过无声转换避免意外

    • 易于理解

    • 没有硬编码限制

    #include <string>
    #include <sstream>
    #include <iomanip>
    
    /// Vertextet einen Ganzzahlwert val im Hexadezimalformat.
    /// Auf die Minimal-Breite width wird mit führenden Nullen aufgefüllt;
    /// falls nicht angegeben, wird diese Breite aus dem Typ des Arguments
    /// abgeleitet. Funktion geeignet von char bis long long.
    /// Zeiger, Fließkommazahlen u.ä. werden nicht unterstützt, ihre
    /// Übergabe führt zu einem (beabsichtigten!) Compilerfehler.
    /// Grundlagen aus: http://stackoverflow.com/a/5100745/2932052
    template <typename T>
    inline std::string int_to_hex(T val, size_t width=sizeof(T)*2)
    {
        std::stringstream ss;
        ss << std::setfill('0') << std::setw(width) << std::hex << (val|0);
        return ss.str();
    }
    

    [1]根据答案Kornel Kisielewicz
    [2]翻译成CppTest的语言,它的内容如下:

    TEST_ASSERT(int_to_hex(char(0x12)) == "12");
    TEST_ASSERT(int_to_hex(short(0x1234)) == "1234");
    TEST_ASSERT(int_to_hex(long(0x12345678)) == "12345678");
    TEST_ASSERT(int_to_hex((long long)(0x123456789abcdef0)) == "123456789abcdef0");
    TEST_ASSERT(int_to_hex(0x123, 1) == "123");
    TEST_ASSERT(int_to_hex(0x123, 8) == "00000123");
    
  • 20

    这个问题很老,但我很惊讶为什么没有人提到 boost::format

    cout << (boost::format("%x") % 1234).str();  // output is: 4d2
    
  • 13

    感谢林肯的评论,我已经改变了这个答案 .

    以下答案在编译时正确处理8位整数 . 然而,它需要C 17.如果你没有C 17,你将不得不做其他事情(例如提供这个函数的重载,一个用于uint8_t,一个用于int8_t,或者使用除了“if constexpr”之外的东西) ,也许enable_if) .

    template< typename T >
    std::string int_to_hex( T i )
    {
        // Ensure this function is called with a template parameter that makes sense. Note: static_assert is only available in C++11 and higher.
        static_assert(std::is_integral<T>::value, "Template argument 'T' must be a fundamental integer type (e.g. int, short, etc..).");
    
        std::stringstream stream;
        stream << "0x" << std::setfill ('0') << std::setw(sizeof(T)*2) << std::hex;
    
        // If T is an 8-bit integer type (e.g. uint8_t or int8_t) it will be 
        // treated as an ASCII code, giving the wrong result. So we use C++17's
        // "if constexpr" to have the compiler decides at compile-time if it's 
        // converting an 8-bit int or not.
        if constexpr (std::is_same_v<std::uint8_t, T>)
        {        
            // Unsigned 8-bit unsigned int type. Cast to int (thanks Lincoln) to 
            // avoid ASCII code interpretation of the int. The number of hex digits 
            // in the  returned string will still be two, which is correct for 8 bits, 
            // because of the 'sizeof(T)' above.
            stream << static_cast<int>(i);
        }        
        else if (std::is_same_v<std::int8_t, T>)
        {
            // For 8-bit signed int, same as above, except we must first cast to unsigned 
            // int, because values above 127d (0x7f) in the int will cause further issues.
            // if we cast directly to int.
            stream << static_cast<int>(static_cast<uint8_t>(i));
        }
        else
        {
            // No cast needed for ints wider than 8 bits.
            stream << i;
        }
    
        return stream.str();
    }
    

    Original answer that doesn't handle 8-bit ints correctly as I thought it did:

    Kornel Kisielewicz的答案很棒 . 但是稍微添加有助于捕获使用无意义的模板参数调用此函数的情况(例如float)或者会导致编译器错误(例如用户定义的类型) .

    template< typename T >
    std::string int_to_hex( T i )
    {
      // Ensure this function is called with a template parameter that makes sense. Note: static_assert is only available in C++11 and higher.
      static_assert(std::is_integral<T>::value, "Template argument 'T' must be a fundamental integer type (e.g. int, short, etc..).");
    
      std::stringstream stream;
      stream << "0x" 
             << std::setfill ('0') << std::setw(sizeof(T)*2) 
             << std::hex << i;
    
             // Optional: replace above line with this to handle 8-bit integers.
             // << std::hex << std::to_string(i);
    
      return stream.str();
    }
    

    我编辑了这个来添加对std :: to_string的调用,因为将 std::stringstream 的8位整数类型(例如传递给 std::uint8_t 的值)视为char,它不会给你想要的结果 . 将这样的整数传递给 std::to_string 正确处理它们并且在使用其他更大的整数类型时不会损害它们 . 当然,在这些情况下你可能会遇到轻微的性能损失,因为std :: to_string调用是不必要的 .

    注意:我会在对原始答案的评论中添加此内容,但我没有代表发表评论 .

  • 1

    代码供您参考:

    #include <iomanip>
    ...
    string intToHexString(int intValue) {
    
        string hexStr;
    
        /// integer value to hex-string
        std::stringstream sstream;
        sstream << "0x"
                << std::setfill ('0') << std::setw(2)
        << std::hex << (int)intValue;
    
        hexStr= sstream.str();
        sstream.clear();    //clears out the stream-string
    
        return hexStr;
    }
    
  • 2

    我做:

    int hex = 10;      
    std::string hexstring = stringFormat("%X", hex);
    

    看看来自iFreilicht的SO回答和所需的模板头文件GIST

  • 0

    `

    char sw(int num){
       char h[16] = {'0','1','2','3','4','5','6','7','8','9','a','b',' c','d','e','f'};
       return h[num];
    }
    
    String to_hexa(int num) {
      int i, j, exp = 0, temp = num;
      String hexa;
      String begin;
    
    
      while( temp >= 16 ){
        exp++;
        temp /= 16;
      }
    
      for ( i = 0; i <= exp; ++i){
        temp = num;
        for ( j = i; j <= exp; ++j){
          if ( j == exp ) hexa += String(sw(temp % 16));
          else temp /= 16;
        }
      }
      begin = "0x";
      for (int i=0; i < 3 - exp; i++){
        begin += "0";
      }  
      return begin + hexa;
    }
    

    `

  • -1

    试试这个:

    #include<iostream>
    
    using namespace std;
    
    int main() {
        int *a = new int;//or put a number exept new int
                         //use * for pointer
        cin >> *a;
        cout << a; //if integer that is made as pointer printed without *, than it will print hex value
        return 0;
        //I hope i help you
    }
    

相关问题