Wrong number produced when memcpy-ing data into an integer?

I have a char buffer like this

char *buff = "aaaa0006france";

I want to extract the bytes 4 to 7 and store it in an int.

int i;
memcpy(&i, buff+4, 4);
printf("%d ", i);

But it prints junk values.

What is wrong with this?

Answers


Here you need to note down two things

  • How the characters are stored
  • Endianess of the system

Each characters (Alphabhets, numbers or special characters) are stored as 7 bit ASCII values. While doing memcpy of the string(array of characters) "0006" to a 4bytes int variable, we have to give address of string as source and address of int as destination like below.

char a[] = "0006";
int b = 0, c = 6;
memcpy(&b, a, 4);

Values of a and b are stored as below.

a 00110110 00110000 00110000 00110000
b 00000000 00000000 00000000 00000000
c 00000000 00000000 00000000 00000110
  MSB                             LSB

Because ASCII value of 0 character is 48 and 6 character is 54. Now memcpy will try to copy whatever value present in the a to b. After memcpy value of b will be as below

a 00110110 00110000 00110000 00110000
b 00110110 00110000 00110000 00110000
c 00000000 00000000 00000000 00000110
  MSB                             LSB

Next is endianess. Now consider we are keeping the value 0006 to the character buffer in some other way like a[0] = 0; a[1] = 0; a[2]=0; a[3] = 6; now if we do memcpy, we will the get the value as 100663296(0x6000000) not 6 if it is little endian machine. In big endian machine you will get the value as 6 only.

c 00000110 00000000 00000000 00000000
b 00000110 00000000 00000000 00000000
c 00000000 00000000 00000000 00000110
  MSB                             LSB

So these two problems we need to consider while writing a function which converts number charters to integer value. Simple solution for these problem is to make use of existing system api atoi.


The string

0006

does not have the same binary representation as the integer 6. Instead, its bit representation is as four ASCII characters representing the glyph 0, the glyph 0, the glyph 0, then the glyph 6. This has hex representation

0x30303036

If you try blindly reinterpreting these bits as a number on a little-endian system, you get back 808,464,438. On a big-endian system, you'd get 909,127,728.

If you want to convert a substring of your string into a number, you will need to instead look for a function that converts a string of text into a number. You might want to try something like this:

char digits[5];

/* Copy over the digits in question. */
memcpy(digits, buff + 4, 4);
digits[4] = '\0';  /* Make sure it's null-terminated! */

/* Convert the string to a number. */
int i = strtol(digits + 4, NULL, 10);

This uses the strtol function, which converts a text string into a number, to explicitly convert the text to an integer.

Hope this helps!


the below code might help you...

#include <stdio.h>

int main()
{
char *buff = "aaaa0006france";
char digits[5];

memcpy(digits, buff + 4, 4);
digits[4] = '\0';

int a = atoi(digits);
printf("int : %d", a);

return 0;
}

Need Your Help

Populate 3 combobox from same table but use filter in all 3 tables

c# sql winforms

i have a windows application having 3 combobox. username, prepared by, authorized by.

How to make a nice button using Jquery mobile?

jquery file mobile external transition

I want to make a button using jquery mobile to redirect the user to an other page with a slide animation for example and with rel="external" in order to load external js file .

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.