# How can bytes in char array represent integers?

So let's say I have char array that I read from binary file (like ext2 formatted filesystem image file).

Now I need to read integer starting at offset byte 1024(<--that's the offset from start of data). Is there any neat way of doing it. The integer could be any number. So I believe can be represented in integer size of 4 byte on my system (x86-64).

I believe I need to use strtol like:

``````/* Convert the provided value to a decimal long */
char *eptr=malloc(4);// 4 bytes becuase sizeof int is 4 bytes
....
result = strtol(eptr, &v, 10);
``````

The above is `long` so is this the number to represent a integer 32 bit?

Should `eptr` be null terminated?

Is this correct or not?

In the case of `strtol` it might be easier to follow along by seeing some code. So here a very simplified `strtol` kind of function:

``````int string_to_int(const char *string)
{
// The integer value we construct and return
int value = 0;

// Loop over all the characters in the string, one by one,
// until the string null-terminator is reached
for (unsigned i = 0; string[i] != '\0'; ++i)
{
// Get the current character
char c = string[i];

// Convert the digit character to its corresponding numeric value
int c_value = c - '0';

// Add the characters numeric value to the current value
value = (value * 10) + c_value;

// Note the multiplication with 10: That's because decimal numbers are base 10
}

// Now the string have been converted to its decimal integer value, return it
return value;
}
``````

If we call it with the string `"123"` and unroll the loop what's happening is this:

``````// First iteration
char c = string;  // c = '1'
int c_value = c - '0';  // c_value = 1
value = (value * 10) + c_value;  // value = (0 * 10) + 1 = 0 + 1 = 1

// Second iteration
char c = string;  // c = '2'
int c_value = c - '0';  // c_value = 2
value = (value * 10) + c_value;  // value = (1 * 10) + 2 = 10 + 2 = 12

// Third iteration
char c = string;  // c = '3'
int c_value = c - '0';  // c_value = 3
value = (value * 10) + c_value;  // value = (12 * 10) + 3 = 120 + 3 = 123
``````

In the fourth iteration we reach the string null-terminator and the loop ends with `value` being equal to the `int` value `123`.

I hope this makes it a little clearer about how string to number conversions are working.

While the above is for strings, if you read the raw binary bits of an existing `int` value, then you should not call `strtol` because the data isn't a string.

Instead you basically interpret the four bytes as a single 32-bit value.

Unfortunately it's not easy to explain how these bits are interpreted without knowing a thing or two about endianness.

Endianness is how the bytes are ordered to make up the integer value. Taking the (hexadecimal) number `0x01020304` they can be stored either as `0x01`, `0x02`, `0x03` and `0x04` (this is called big-endian); Or as `0x04`, `0x03`, `0x02` and `0x01` (this is called little-endian).

On a little-endian system (your normal PC-like system) say you have an array like this:

``````char bytes = { 0x04, 0x03, 0x02, 0x01 };
``````

then you could copy it into an `int`:

``````int value;
memcpy(&value, bytes, 4);
``````

and that will make the `int` variable `value` equal to `0x01020304`.

I have char array that I read from binary file (like ext2 formatted filesystem image file).

Open the file in binary mode

``````const char *file_name = ...;
FILE *infile = fopen(file_name, "rb");  // b is for binary
if (infile == NULL) {
fprintf(stderr, "Unable to open file <%s>.\n", file_name);
exit(1);
}
``````

I need to read integer starting at offset byte 1024 ...

``````long offset = 1024;
if (fseek(infile, offset, SEEK_SET)) {
fprintf(stderr, "Unable to seek to %ld.\n", offset);
exit(1);
}
``````

So I believe can be represented in integer size of 4 byte on my system

Rather than use `int`, which may differ from 4-bytes, consider `int32_t` from `<stdint.h>`.

``````int32_t data4;
if (fread(&data4, sizeof data4, 1, infile) != 1) {
exit(1);
}
``````

Account for Endian.

As file data is little-endian, convert to native endian. See `#include <endian.h>`.

``````data4 = le32toh(data4);
``````

Clean up when done

``````// Use data4

fclose(infile);
``````

believe I need to use `strtol` like

No. `strtol()` examines a string and returns a `long`. File data is binary and not a string.