代码之家  ›  专栏  ›  技术社区  ›  Jacob Nelson

将int转换为4字节字符数组(C)

c
  •  60
  • Jacob Nelson  · 技术社区  · 14 年前

    嘿,我想把用户输入的一个int转换成4个字节,分配给一个字符数组。如何做到这一点?

    例子:

    00000000 00000000 00000000 10101111


    0 0 0 ff 尽管打印出来的是: 0 0 0 ffffffff

    unsigned int value = 255;   
    
    buffer[0] = (value >> 24) & 0xFF;
    buffer[1] = (value >> 16) & 0xFF;
    buffer[2] = (value >> 8) & 0xFF;
    buffer[3] = value & 0xFF;
    
    union {
        unsigned int integer;
        unsigned char byte[4];
    } temp32bitint;
    
    temp32bitint.integer = value;
    buffer[8] = temp32bitint.byte[3];
    buffer[9] = temp32bitint.byte[2];
    buffer[10] = temp32bitint.byte[1];
    buffer[11] = temp32bitint.byte[0];
    

    两者都会导致 0 0 ffffff 而不是

    另一个例子是175,输入输出为 0, 0, 0, ffffffaf 当它应该是 0, 0, 0, af

    10 回复  |  直到 13 年前
        1
  •  153
  •   betabandido    13 年前

    这个 便携式的 0x00 0x00 0x00 0xaf 任何地方)都要轮班:

    unsigned char bytes[4];
    unsigned long n = 175;
    
    bytes[0] = (n >> 24) & 0xFF;
    bytes[1] = (n >> 16) & 0xFF;
    bytes[2] = (n >> 8) & 0xFF;
    bytes[3] = n & 0xFF;
    

    使用并集和 memcpy()


    你的问题是印刷而不是转换。我猜你在用 char 而不是 unsigned char ,您将使用这样的行来打印它:

    printf("%x %x %x %x\n", bytes[0], bytes[1], bytes[2], bytes[3]);
    

    当任何类型比 int 传递给 printf ,他们被提升为 (或 unsigned int 内景 无法保存原始类型的所有值)。如果 烧焦 在你的平台上签名,然后呢 0xff 可能不适合该类型的范围,而是将其设置为-1(具有表示形式) 0xff型 在机器上)。

    内景 ,并具有 0xffffffff 作为一个 内景 在你的机器上,这就是你看到的。

    无符号字符 无符号字符 打印F

    printf("%x %x %x %x\n", (unsigned char)bytes[0],
                            (unsigned char)bytes[1],
                            (unsigned char)bytes[2],
                            (unsigned char)bytes[3]);
    
        2
  •  15
  •   Blastfurnace    14 年前

    是否要寻址32位int的各个字节?一种可能的方法是联合:

    union
    {
        unsigned int integer;
        unsigned char byte[4];
    } foo;
    
    int main()
    {
        foo.integer = 123456789;
        printf("%u %u %u %u\n", foo.byte[3], foo.byte[2], foo.byte[1], foo.byte[0]);
    }
    

    注意:已更正printf以反映无符号值。

        3
  •  7
  •   villapx    9 年前

    在您的问题中,您声明要将175的用户输入转换为 00000000 00000000 00000000 10101111 ,即 大端 字节排序,也称为 .

    A htonl() 函数(在标题中定义 <arpa/inet.h> 在Linux系统上),将无符号int转换为big endian字节顺序,然后使用 memcpy() (在标题中定义) <string.h> 对于C, <cstring> 对于C++,将字节复制到char(或无符号char)数组中。

    这个 htonl() 函数接受一个无符号32位整数作为参数(与 htons() ,它接受一个无符号的16位整数)并将其从主机字节顺序转换为网络字节顺序(因此缩写为host to network Long,而不是host to network Short) htons ),将结果返回为无符号32位整数。这一系列函数的目的是确保所有网络通信都以大端字节顺序进行,以便所有机器都可以通过套接字进行通信,而不会出现字节顺序问题。(另一方面,对于big endian机器 htonl() , ntohl() ntohs() 函数通常被编译成“no op”,因为字节在通过套接字发送或从套接字接收之前不需要翻转,因为它们已经处于正确的字节顺序)

    代码如下:

    #include <stdio.h>
    #include <arpa/inet.h>
    #include <string.h>
    
    int main() {
        unsigned int number = 175;
    
        unsigned int number2 = htonl(number);
        char numberStr[4];
        memcpy(numberStr, &number2, 4);
    
        printf("%x %x %x %x\n", numberStr[0], numberStr[1], numberStr[2], numberStr[3]);
    
        return 0;
    }
    

    使用printf的字符 %x 格式说明符。

    上面的代码打印出来 0 0 0 af 在我的机器上(一台x86\u64机器,它使用小端字节排序),它是175的十六进制。

        4
  •  2
  •   jbernadas    14 年前

    void CopyInt(int value, char* buffer) {
      memcpy(buffer, (void*)value, sizeof(int));
    }
    
        5
  •  1
  •   Luiz Felipe    12 年前

    因为cpp不允许指针之间的直接转换,所以需要使用reinterpret\u cast或casting to void*来完成这项工作。

        6
  •  0
  •   gandjustas    14 年前
    int a = 1;
    char * c = (char*)(&a); //In C++ should be intermediate cst to void*
    
        7
  •  -1
  •   Enusi    9 年前

    转换的问题(它在结尾给您一个ffffff的原因)是因为十六进制整数(您使用的是二进制运算符)被解释为有符号的。把它转换成一个无符号整数,你就没事了。

        8
  •  -1
  •   Franco Méndez    7 年前

    int 相当于 uint32_t char uint8_t

    我将展示如何解析客户机-服务器通信,在1位数组中发送实际时间(4字节,在Unix epoch中格式化),然后在另一端重新构建它。(注:协议发送1024字节)

    • 客户端

      uint8_t message[1024];
      uint32_t t = time(NULL);
      
      uint8_t watch[4] = { t & 255, (t >> 8) & 255, (t >> 16) & 255, (t >> 
      24) & 255 };
      
      message[0] = watch[0];
      message[1] = watch[1];
      message[2] = watch[2];
      message[3] = watch[3];
      send(socket, message, 1024, 0);
      
    • 服务器端

      uint8_t res[1024];
      uint32_t date;
      
      recv(socket, res, 1024, 0);
      
      date = res[0] + (res[1] << 8) + (res[2] << 16) + (res[3] << 24);
      
      printf("Received message from client %d sent at %d\n", socket, date);
      

    希望有帮助。

        9
  •  -2
  •   Dr. Sahib    11 年前

    union {
    unsigned int integer;
    char byte[4];
    } temp32bitint;
    

    并在打印时强制转换,以防止升级到“int”(默认情况下C会这样做)

    printf("%u, %u \n", (unsigned char)Buffer[0], (unsigned char)Buffer[1]);
    
        10
  •  -2
  •   pushkin Void Star    6 年前

    你可以简单地使用 memcpy

    unsigned int value = 255;
    char bytes[4] = {0, 0, 0, 0};
    memcpy(bytes, &value, 4);