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

时间:2010-09-24 04:50:24

标签: c

嘿,我正在寻找将用户输入的int转换为4个字节,我将其分配给字符数组。怎么办呢?

示例:

将用户输入175转换为

00000000 00000000 00000000 10101111


到目前为止所有答案的问题,转换255应该会产生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 0 ffffffff而不是0 0 0 ff

另一个示例是175,因为输入打印为0, 0, 0, ffffffaf时它应该只是0, 0, 0, af

10 个答案:

答案 0 :(得分:130)

便携式执行此操作的方式(确保您到处获得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,则会将其提升为int(或unsigned int,如果int无法保留所有值原始类型)。如果您的平台上已签署char,那么0xff可能不适合该类型的范围,而是将其设置为-1(其中的代表0xff 2s补充机器。)

-1升级为int,并在您的计算机上将0xffffffff表示为int,这就是您所看到的。

您的解决方案是实际使用unsigned char,或者在unsigned char声明中转换为printf

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

答案 1 :(得分: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以反映无符号值。

答案 2 :(得分:6)

在您的问题中,您声明要将用户输入175转换为 00000000 00000000 00000000 10101111 big endian 字节排序,也称为网络字节顺序

可移植的方式将无符号整数转换为大端无符号字符数组,正如您在“175”示例中所建议的那样,将使用C的htonl()函数(在Linux系统上的标头<arpa/inet.h>中定义)将unsigned int转换为big endian字节顺序,然后使用memcpy()(在标头<string.h>中为C定义,<cstring> for C ++)将字节复制到char(或unsigned char)数组中。

htonl()函数接受无符号的32位整数作为参数(与htons()相反,后者接收无符号的16位整数)并将其转换为网络字节顺序主机字节顺序(因此首字母缩写,主机TO网络长,而主机TO网络短路为htons),返回结果为无符号32位整数。此系列函数的目的是确保所有网络通信都以大端字节顺序发生,以便所有计算机可以通过套接字相互通信而不会出现字节顺序问题。 (顺便说一句,对于大端机器,htonl()htons()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;
}

请注意,正如caf所说,您必须使用printf的%x格式说明符将字符打印为无符号字符。

上面的代码在我的机器上打印0 0 0 af(x86_64机器,它使用小端字节排序),这是175的十六进制。

答案 3 :(得分:2)

您可以尝试:

void CopyInt(int value, char* buffer) {
  memcpy(buffer, (void*)value, sizeof(int));
}

答案 4 :(得分:1)

为什么在C ++中需要中间强制转换为void * 因为cpp不允许在指针之间进行直接转换,所以你需要使用reinterpret_cast或者转换为void *来做事情。

答案 5 :(得分:0)

int a = 1;
char * c = (char*)(&a); //In C++ should be intermediate cst to void*

答案 6 :(得分:-1)

转换的问题(它最后给你一个ffffff的原因)是因为你的十六进制整数(你正在使用&amp;二元运算符)被解释为被签名。将它转换为无符号整数,你会没事的。

答案 7 :(得分:-1)

int相当于uint32_tchar相当于uint8_t

我将展示如何解决客户端 - 服务器通信,以1位数组发送实际时间(4个字节,在Unix纪元中格式化),然后在另一侧重新构建它。 (注意:协议是发送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);
    

希望它有所帮助。

答案 8 :(得分:-2)

问题出现了,因为unsigned char是一个4字节的数字,而不是许多人认为的1字节数,因此将其更改为

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

并在打印时进行转换,以防止提升为'int'(默认情况下C默认)

printf("%u, %u \n", (unsigned char)Buffer[0], (unsigned char)Buffer[1]);

答案 9 :(得分:-2)

您可以按如下方式简单地使用memcpy

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