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로 설정됩니다 ( 0xff
2s 보완 시스템에서 표시됨).
-1로 승격 int
하고, 표현이 0xffffffff
AS를 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
'Programing' 카테고리의 다른 글
XAML의 * .resx 파일에서 값 가져 오기 (0) | 2020.11.14 |
---|---|
스타일이 지정되지 않은 콘텐츠의 플래시 제거 (0) | 2020.11.14 |
C ++ 열거 형은 정수보다 사용 속도가 느립니까? (0) | 2020.11.14 |
Java에서 enum의 서수를 지정할 수 있습니까? (0) | 2020.11.14 |
SQL의 삭제 문이 매우 느립니다. (0) | 2020.11.14 |