Convert int to 4 byte char (C) array

Hey, I want to convert an int that the user enters into 4 bytes, which I assign to an array of characters. How can I do that?

Example:

Convert user inputs from 175 to

00000000 00000000 00000000 10101111




The problem with all the answers so far, the 255 conversion should lead to 0 0 0 ff , although it is output as: 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]; 

both results are 0 0 0 ffffffff instead of 0 0 0 ff

Another example is 175, because the input is printed as 0, 0, 0, ffffffaf , when it should only be 0, 0, 0, af

+57
c
Sep 24 '10 at 4:50
source share
11 answers

A portable way to do this (ensuring you get 0x00 0x00 0x00 0xaf everywhere) is to use shifts:

 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; 

Methods using unions and memcpy() will get different results on different machines.




The problem you are facing is with printing, not conversion. I suppose you are using char , not unsigned char , and for printing you use this line:

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

If any types narrower than int are passed to printf , they are promoted to int (or unsigned int if int cannot contain all the values ​​of the original type). If char signed on your platform, then 0xff probably does not fit into the range of this type, and instead it is set to -1 (which has a 0xff on the machine with 2s added).

-1 advances to int and has the representation of 0xffffffff as int on your computer, and this is what you see.

Your solution is to either use unsigned char or use unsigned char in the printf statement:

 printf("%x %x %x %x\n", (unsigned char)bytes[0], (unsigned char)bytes[1], (unsigned char)bytes[2], (unsigned char)bytes[3]); 
+122
24 Sep '10 at 5:38
source share
β€” -

Do you want to access the individual bytes of a 32-bit int? One possible method is combining:

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

Note: fixed printf value to reflect unsigned values.

+15
Sep 24 '10 at 5:11
source share

In your question, you stated that you want to convert user input from 175 to 00000000 00000000 00000000 10101111 , which is a large byte order of bytes, also known as network byte order.

Basically a portable way to convert your unsigned integer to an unsigned array of unsigned char, as you suggested from this example, β€œ175” you specified will use the C htonl() function (defined in the header on Linux systems) to convert your unsigned int into the byte order of large endian, then use memcpy() (defined in the header <string.h> for C, <cstring> for C ++) to copy the bytes into your char (or unsigned char).

The htonl() function takes an unsigned 32-bit integer as an argument (unlike htons() , which takes an unsigned 16-bit integer) and converts it to the network byte order from the host byte order (hence the abbreviation, Host TO Network Long , against Host TO Network Short for htons ), returning the result as a 32-bit unsigned integer. The purpose of this family of functions is to ensure that all network communications are executed in large byte order, so that all machines can communicate with each other via a socket without problems with byte order. (Aside, for large-end machines, the htonl() , htons() , ntohl() and ntohs() are usually compiled to simply be "no op" because bytes do not need to be reversed before they are sent or received from socket, as they are already in the correct byte order)

Here is 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 need to print characters as unsigned characters using the printf %x format specifier.

The above code prints 0 0 0 af on my machine (an x86_64 machine that uses a small ordinal number of bytes), which is hexadecimal for 175.

+6
Jan 21 '16 at 17:19
source share

You can try:

 void CopyInt(int value, char* buffer) { memcpy(buffer, (void*)value, sizeof(int)); } 
+3
Sep 24 '10 at 4:55
source share
 int a = 1; char * c = (char*)(&a); //In C++ should be intermediate cst to void* 
+1
Sep 24 '10 at 4:53
source share

Why do you need an intermediate listing in void * in C ++ Since cpp does not allow direct conversion between pointers, you need to use reinterpret_cast or casting for void * does the thing.

+1
Jun 16 '13 at 21:08
source share

The conversion problem (the reason it gives you ffffff at the end) is because your hex integer (with which you use the binary operator c) is interpreted as signed. Add it to an unsigned integer and everything will be fine.

0
Feb 24 '16 at 21:26
source share

An int equivalent to uint32_t and char is uint8_t .

I will show how I allowed client-server communication by sending the actual time (4 bytes formatted in the Unix era) in a 1-bit array, and then rebuilding it from the other side. (Note: the protocol should have sent 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 this helps.

0
Oct 30 '17 at 21:38
source share

You can simply use memcpy as follows:

 unsigned int value = 255; char bytes[4] = {0, 0, 0, 0}; memcpy(bytes, &value, 4); 
0
Nov 21 '18 at 16:09
source share

I think this is the simplest and most effective solution:

 unsigned char bytes[4]; unsigned int number = 123456; *(unsigned int*)bytes = number 
0
Jan 11 '19 at 8:46
source share

The problem arises because an unsigned char is a 4-byte number, not 1 byte, as many think, so change it to

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

and pronounce during printing to prevent progress to 'int' (which is C by default)

 printf("%u, %u \n", (unsigned char)Buffer[0], (unsigned char)Buffer[1]); 
-one
Jul 07 '14 at 15:23
source share



All Articles