Programing

int를 4 바이트 문자 배열로 변환 (C)

lottogame 2020. 11. 14. 09:45
반응형

int를 4 바이트 문자 배열로 변환 (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


이를 수행하는 휴대용 방법 ( 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로 설정됩니다 ( 0xff2s 보완 시스템에서 표시됨).

-1로 승격 int하고, 표현이 0xffffffffAS를 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]);

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를 수정했습니다.


귀하의 질문에, 당신은 당신이 175의 사용자 입력 변환 할 것을 주장 00000000 00000000 00000000 10101111하고, 빅 엔디안 이라고도 바이트 순서, 네트워크 바이트 순서를 .

A mostly portable way to convert your unsigned integer to a big endian unsigned char array, as you suggested from that "175" example you gave, would be to use C's htonl() function (defined in the header <arpa/inet.h> on Linux systems) to convert your unsigned int to big endian byte order, then use memcpy() (defined in the header <string.h> for C, <cstring> for C++) to copy the bytes into your char (or unsigned char) array.

The htonl() function takes in an unsigned 32-bit integer as an argument (in contrast to htons(), which takes in an unsigned 16-bit integer) and converts it to network byte order from the host byte order (hence the acronym, Host TO Network Long, versus Host TO Network Short for htons), returning the result as an unsigned 32-bit integer. The purpose of this family of functions is to ensure that all network communications occur in big endian byte order, so that all machines can communicate with each other over a socket without byte order issues. (As an aside, for big-endian machines, the htonl(), htons(), ntohl() and ntohs() functions are generally compiled to just be a 'no op', because the bytes do not need to be flipped around before they are sent over or received from a socket since they're already in the proper byte order)

Here's the code:

#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;
}

Note that, as caf said, you have to print the characters as unsigned characters using printf's %x format specifier.

The above code prints 0 0 0 af on my machine (an x86_64 machine, which uses little endian byte ordering), which is hex for 175.


You can try:

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

Why would you need an intermediate cast to void * in C++ Because cpp doesn't allow direct conversion between pointers, you need to use reinterpret_cast or casting to void* does the thing.


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

The issue with the conversion (the reason it's giving you a ffffff at the end) is because your hex integer (that you are using the & binary operator with) is interpreted as being signed. Cast it to an unsigned integer, and you'll be fine.


An int is equivalent to uint32_t and char to uint8_t.

I'll show how I resolved client-server communication, sending the actual time (4 bytes, formatted in Unix epoch) in a 1-bit array, and then re-built it in the other side. (Note: the protocol was to send 1024 bytes)

  • Client side

    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);
    
  • Server side

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

Hope it helps.


The problem is arising as unsigned char is a 4 byte number not a 1 byte number as many think, so change it to

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

and cast while printing, to prevent promoting to 'int' (which C does by default)

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

You can simply use memcpy as follows:

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

참고URL : https://stackoverflow.com/questions/3784263/converting-an-int-into-a-4-byte-char-array-c

반응형