Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copying a 4 element character array into an integer in C

Tags:

c

A char is 1 byte and an integer is 4 bytes. I want to copy byte-by-byte from a char[4] into an integer. I thought of different methods but I'm getting different answers.

char str[4]="abc";
unsigned int a = *(unsigned int*)str;
unsigned int b = str[0]<<24 | str[1]<<16 | str[2]<<8 | str[3];
unsigned int c;
memcpy(&c, str, 4);
printf("%u %u %u\n", a, b, c);

Output is 6513249 1633837824 6513249

Which one is correct? What is going wrong?

like image 440
avmohan Avatar asked Oct 11 '13 17:10

avmohan


People also ask

How to copy a string from an array to another array in C?

strcpy can be used to copy one string to another. Remember that C strings are character arrays. You must pass character array, or pointer to character array to this function where string will be copied. The destination character array is the first parameter to strcpy .

How to copy char value in C?

The C library function char *strncpy(char *dest, const char *src, size_t n) copies up to n characters from the string pointed to, by src to dest. In a case where the length of src is less than that of n, the remainder of dest will be padded with null bytes.

How do I copy a char array to another character array?

The simplest way to copy a character array to another character array is to use memcpy. If you want to copy all elements of array src of size m to array dst of size n, you can use the following code. char src[m]; char dst[n];

How do I copy an int to a char array?

One method to convert an int to a char array is to use sprintf() or snprintf(). This function can be used to combine a number of variables into one, using the same formatting controls as fprintf(). int sprintf ( char *buf, const char *format, ... ); int snprintf( char *buf, size_t n, const char *format, ... );


Video Answer


1 Answers

It's an endianness issue. When you interpret the char* as an int* the first byte of the string becomes the least significant byte of the integer (because you ran this code on x86 which is little endian), while with the manual conversion the first byte becomes the most significant.

To put this into pictures, this is the source array:

   a      b      c      \0
+------+------+------+------+
| 0x61 | 0x62 | 0x63 | 0x00 |  <---- bytes in memory
+------+------+------+------+

When these bytes are interpreted as an integer in a little endian architecture the result is 0x00636261, which is decimal 6513249. On the other hand, placing each byte manually yields 0x61626300 -- decimal 1633837824.

Of course treating a char* as an int* is undefined behavior, so the difference is not important in practice because you are not really allowed to use the first conversion. There is however a way to achieve the same result, which is called type punning:

union {
    char str[4];
    unsigned int ui;
} u;

strcpy(u.str, "abc");
printf("%u\n", u.ui);
like image 92
Jon Avatar answered Oct 15 '22 00:10

Jon