【问题标题】:Converting an int to a 2 byte hex value in C在 C 中将 int 转换为 2 字节的十六进制值
【发布时间】:2011-05-04 09:23:49
【问题描述】:

我需要将 int 转换为 2 字节十六进制值以存储在 C 中的 char 数组中。我该怎么做?

【问题讨论】:

  • int 数据类型是 32 位,而 2 字节的十六进制值是 8 位。如果您的 int > 255 它不适合您的十六进制值(它会溢出)。你的意思是有符号/无符号字符而不是整数?
  • @wez:int 不一定是 32 位的。但是你的问题很好,他确实需要注意溢出。
  • 这个问题看起来像一个家庭作业......这是真的吗?如果是,请添加“作业”标签。
  • @Denilson: "The homework tag, like other so-called 'meta' tags, is now discouraged," 但是,@MikeU,请(一如既往)遵循general guidelines,说明任何特殊限制,展示您迄今为止尝试过的内容,并询问具体是什么令人困惑你。

标签: c string hex


【解决方案1】:

如果您被允许使用库函数:

int x = SOME_INTEGER;
char res[5]; /* two bytes of hex = 4 characters, plus NULL terminator */

if (x <= 0xFFFF)
{
    sprintf(&res[0], "%04x", x);
}

您的整数可能包含超过四个十六进制数字的数据,因此请先检查。

如果不允许使用库函数,请手动将其划分为 nybbles:

#define TO_HEX(i) (i <= 9 ? '0' + i : 'A' - 10 + i)

int x = SOME_INTEGER;
char res[5];

if (x <= 0xFFFF)
{
    res[0] = TO_HEX(((x & 0xF000) >> 12));   
    res[1] = TO_HEX(((x & 0x0F00) >> 8));
    res[2] = TO_HEX(((x & 0x00F0) >> 4));
    res[3] = TO_HEX((x & 0x000F));
    res[4] = '\0';
}

【讨论】:

  • 从看到其他人的答案来看,他们似乎在解释“两字节十六进制值”,意思是两个 nybbles,每个 nybbles 由一个字节十六进制字符表示。我把它理解为两个字节的数据,每个字节由两个十六进制字符表示。你需要澄清你的意思!
  • 感谢@Vicky 的回答。用它来构建下面答案中的函数。
【解决方案2】:

假设 int 为 32 位;

最简单的方法:只需使用 sprintf()

int intval = /*your value*/
char hexval[5];
sprintf(hexval,"%0x",intval);

现在使用 hexval[0] 到 hexval[3];如果您想将其用作以 null 结尾的字符串,请添加 hexval[4]=0;

【讨论】:

  • 当 0xFF 时你会得到不可预知的结果(甚至崩溃)
  • 不。由于 sprintf 将 intval 格式化为字符串。所以 0xFFFF(顺便说一下,这不是 32 位整数的最大值)将是四个 F,而那些不适合 hexval[3],因为您还必须考虑尾随 0。您不必添加顺便说一下,hexval[2]=0。
【解决方案3】:

想出了一个我测试过的快速方法,它可以工作。

int value = 11;

array[0] = value >> 8;
array[1] = value & 0xff;

printf("%x%x", array[0], array[1]);

结果是:

000B

十六进制为 11。

【讨论】:

    【解决方案4】:
    char s[5];  // 4 chars + '\0'
    int x = 4660;
    sprintf(s, "%04X", x);
    

    您可能需要查看sprintf() 文档。请注意,此代码不是很安全。如果x 大于0xFFFF,则最终字符串将超过 4 个字符且不适合。为了更安全,请看snprintf()

    【讨论】:

    • 如果 int 为 11。我需要得到的 2 个字节为 0 B,即十六进制的 11。
    • 错了,这两个字符是半字节,也叫半字节。一个字节(8 位,0-255)由 2 个十六进制字符组成。因此,2 个字节由 4 个十六进制字符组成。每个十六进制字符(或半字节)有 4 位(0-15 或 0-F)。
    【解决方案5】:

    通常我会推荐使用其他人推荐的基于sprintf 的解决方案。但是当我编写一个必须将数十亿个项目转换为十六进制的工具时,sprintf 太慢了。对于那个应用程序,我使用了一个 256 元素数组,它将字节映射到字符串。

    这是转换 1 字节的不完整解决方案,不要忘记添加边界检查,并确保数组是静态或全局的,每次检查都重新创建它会降低性能。

    static const char hexvals[][3]= {"00", "01", "02", ... "FD", "FE", "FF"};
    const char *byteStr = hexvals[number];
    

    【讨论】:

      【解决方案6】:

      我建议使用snprintf 而不是sprintf

      #include <stdio.h>
      
      int main()
      {
          char output[5];
          snprintf(output,5,"%04x",255);
      
          printf("%s\n",output);
          return 0;
      }
      

      它更安全,几乎所有编译器都可以使用。

      【讨论】:

        【解决方案7】:
        void intToHex(int intnumber, char *txt)
        {    
            unsigned char _s4='0';
            char i=4;
            //intnumber=0xffff;
        
            do {
                i--;
                _s4 = (unsigned char)  ((intnumber >> i*4 ) & 0x000f);
                if(_s4<10)
                    _s4=_s4+48;
                else
                    _s4=_s4+55;
        
                *txt++= _s4;    
            } while(i);     
        }
        ...
        char text [5]={0,0,0,0,0};
        ...
        
        intToHex(65534,text);
        USART_Write_Text(text);
        ....
        

        【讨论】:

          【解决方案8】:

          也许可以试试这样的:

          void IntToHex(int value, char* buffer) {
            int a = value&16;
            int b = (value>>4)&16;
            buffer[0] = (a<10)?'0'+a:'A'-(a-10);
            buffer[1] = (b<10)?'0'+b:'A'-(b-10);
          }
          

          【讨论】:

          • 此代码假定字母 A 到 F 占据连续的代码点。 C 语言不保证这一点。
          • 你能想到没有连续字母的任何实现或编码吗?
          • 仍然是一个不错的答案,应该包括 Baudot 代码和 code-UPP..
          【解决方案9】:

          这些答案中的大多数都很棒,我只想补充一件事:您可以使用 sizeof 安全地保留正确的字节数。每个字节最多可以占用两个十六进制数字(255 -> ff),因此每个字节有两个字符。在此示例中,我为“0x”前缀添加了两个字符,为结尾的 NUL 添加了一个字符。

          int bar; 
          // ...
          char foo[sizeof(bar) * 2 + 3];
          sprintf(foo, "0x%x", bar);
          

          【讨论】:

            【解决方案10】:
            unsigned int hex16 = ((unsigned int) input_int) & 0xFFFF;
            

            input_int 是您要转换的数字。 hex16 将具有input_int 的最低有效 2 个字节。如果要将其打印到控制台,请使用%x 作为格式说明符而不是%d,它将以十六进制格式打印。

            【讨论】:

              【解决方案11】:

              这是一种粗略的做法。如果我们不能相信 ascii 值的编码是连续的,我们只需在 char 中创建一个十六进制值的映射。可能可以优化、整理并变得更漂亮。还假设我们只查看捕获最后 32 位 == 4 个十六进制字符。

              #include <stdlib.h>
              #include <stdio.h>
              
              #define BUFLEN 5
              
              int main(int argc, char* argv[])
              {
                int n, i, cn;
                char c, buf[5];
                char hexmap[17] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','.'};
              
                for(i=0;i<BUFLEN;i++)
                  buf[i]=0;
              
                if(argc<2)
                {
                  printf("usage: %s <int>\n", argv[0]);
                  return 1;
                }
                n = atoi(argv[1]);
                i = 0;
                printf("n: %d\n", n);
              
                for(i=0; i<4; i++)
                {
                  cn = (n>>4*i) & 0xF;
                  c  = (cn>15) ? hexmap[16] : hexmap[cn];
                  printf("cn: %d, c: %c\n", cn, c);
              
                  buf[3-i] = (cn>15) ? hexmap[16] : hexmap[cn];
                }
                buf[4] = '\0'; // null terminate it
              
                printf("buf: %s\n", buf);
                return 0;
              }
              

              【讨论】:

              • 32 位 / 4 位/十六进制字符 = 8 个字符。不是 4。
              【解决方案12】:

              这个功能就像一个魅力。

              void WORD2WBYTE(BYTE WBYTE[2], WORD Value) { 
                  BYTE tmpByte[2]; 
                  // Converts a value from word to word byte ----
                  memcpy(tmpByte, (BYTE*) & Value, 2); 
                  WBYTE[1] = tmpByte[0]; 
                  WBYTE[0] = tmpByte[1]; 
              } 
              

              总结如下:

              typedef unsigned char   BYTE; 
              typedef unsigned short  WORD;
              

              使用示例:

              我们希望实现这一目标:

              integer = 92
              byte array in hex:
              a[0] = 0x00;
              a[1] = 0x5c;
              
              unsigned char _byteHex[2];
              WORD2WBYTE(_byteHex, 92);
              

              【讨论】:

                【解决方案13】:

                您可以使用它,它简单易转换

                typedef union {
                    struct hex{
                            unsigned  char a;
                            unsigned  char b;
                
                    }hex_da;
                    short int dec_val;
                }hex2dec;
                
                hex2dec value;
                value.dec_val=10;
                

                现在十六进制值存储在 hex_da 结构中访问它以供进一步使用。

                【讨论】:

                  【解决方案14】:

                  使用上面 Vicky 的答案

                  typedef unsigned    long    ulong;
                  typedef unsigned    char    uchar;
                  
                  #define TO_HEX(i)   (i <= 9 ? '0' + i : 'A' - 10 + i)
                  #define max_strhex  (sizeof(ulong)*2)
                  
                  public uchar
                  *mStrhex(uchar *p, ulong w, ulong n)
                  {
                      ulong i = 0xF;                                  // index
                      ulong mask  = i << (((sizeof(ulong)*2)-1)*4);   // max mask (32 bit ulong mask = 0xF0000000, 16 bit ulong mask = 0xF000)
                      ulong shift = (w*4);                            // set up shift to isolate the highest nibble
                      if(!w || w > max_strhex)                        // no bold params
                          return p;                                   // do nothing for the rebel
                      mask  = mask >> (max_strhex-w)*4;               // setup mask to extract hex nibbles
                      for(i = 0; i < w; i++){                         // loop and add w nibbles
                          shift = shift - 4;                          // hint: start mask for four bit hex is 0xF000, shift is 32, mask >> 32 is 0x0000, mask >> 28 is 0x000F.
                          *p++ = TO_HEX(((n & mask) >> shift));       // isolate digit and make hex
                          mask = mask >> 4;                           //
                          *p = '\0';                                  // be nice to silly people
                      }                                               //
                      return p;                                       // point to null, allow concatenation
                  }
                  

                  【讨论】:

                    【解决方案15】:

                    对于动态固定长度的十六进制

                    string makeFixedLengthHex(const int i, const int length)
                    {
                        std::ostringstream ostr;
                        std::stringstream stream;
                        stream << std::hex << i;
                        ostr << std::setfill('0') << std::setw(length) << stream.str();
                        return ostr.str();
                    }
                    

                    但消极的你必须自己处理。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2012-08-08
                      • 1970-01-01
                      • 2017-03-05
                      • 2011-09-21
                      • 2017-06-17
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-04-18
                      相关资源
                      最近更新 更多