Reputation: 87
Say you have an char array, which holds 8 bytes. How would you convert that char array into an integer?
I tried using sscanf -
int x;
sscanf(char_array, "%d", &x);
I'm reading bytes from a binary file, storing them into a char array, and then I'm trying to print out an int value based on an offset value.
Upvotes: 0
Views: 7391
Reputation: 1899
If you are reading bytes from a binary file, I suggest to read directly from the file to the integer variable. As followed:
#include <stdio.h>
int main() {
FILE *file = fopen("myFile", "r");
int i;
if (file) {
fread(&i, sizeof(i), 1, file);
printf("%d\n", i);
fclose(file);
}
return (0);
}
But if you cannot get rid of your char array as a source for the conversion, you can use a union to easily perform the conversion:
#include <stdio.h>
#include <string.h>
typedef union u_bytes_to_int_type
{
int value;
char bytes[sizeof(int)];
} u_bytes_to_int_type;
void reverseArray(char *array, unsigned int const size) {
char tmp;
unsigned int reverseIdx;
for (unsigned int i = 0; i < size / 2; ++i) {
reverseIdx = size - 1 - i;
tmp = array[i];
array[i] = array[reverseIdx];
array[reverseIdx] = tmp;
}
}
int main() {
char endiannessIsDifferent = 0; // It's up to you how you determine the value of this variable.
char array[sizeof(int)] = {0x2a, 0, 0, 0};
u_bytes_to_int_type v;
memcpy(v.bytes, array, sizeof(array));
/*
** Will reverse the order of the bytes in case the endianness of
** the source array is different from the one you need.
*/
if (endiannessIsDifferent) {
reverseArray(v.bytes, sizeof(v.bytes));
}
printf("%i\n", v.value);
return (0);
}
Upvotes: 0
Reputation: 4473
Is it really char array and not unicode where 2 bytes represent one character? Are you sure result will fit into int? If so, then here is simple solution:
int x=0;
for (int i=0; i<8; i++) x=x*10 + char_array[i]-'0';
Upvotes: 0
Reputation: 31599
I think you just want to read hexadecimal numbers which are usually 8 bytes in text form. You can use this:
sscanf(char_array, "%x", &x);
If it's really binary, it would be 4 bytes each and it depends if the machine is little-endian or big-endian. Most computers are little-endian. To make a portable version, you can use these functions:
#ifdef BIG_ENDIAN
#define memcpy_set(buf,v) memcpy(buf, &v, 4)
#else
#define memcpy_set(buf,v) { for (int i = 0; i < 4; i++) buf[i] = v >> (24 - 8 * i); }
#endif
#define memcpy_get(buf) (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3])
int main()
{
if (sizeof(int) != 4)
return 0;
char buf[5];
memset(buf, 0, 5);
memcpy_set(buf, 0x41424344);
printf("%s\n", buf);// buf = "ABCD"
printf("%x\n", memcpy_get(buf)); //0x41424344
return 0;
}
Upvotes: 1
Reputation: 122
Combining 8 char into an integer would result in a 64-bit integer, so you may need to declare it as unsigned long long int
...
#include <stdio.h>
void showBinary(unsigned long long x) {
int i;
for(i = 63; i >= 0; i--)
printf("%d", x & (1ULL << i) ? 1 : 0);
printf("\n");
}
int main(void) {
char c[8] = {1, 2, 3, 4, 'a', 'b', 'c', 'd'};
unsigned long long int x = 0;
int char_i;
for (char_i = 0; char_i < 8; char_i++) {
x = (x << 8) | c[char_i];
showBinary(x);
}
printf("Result: x = %lld\n", x);
return 0;
}
ps. When you read bytes from file, you may need to be careful about the big-endian or little-endian representation.
Upvotes: 1
Reputation: 134
The following converts a 4 byte array (4 chars) into a 32-bit unsigned integer. You should be able to easily extend this to 8 chars (i.e., 64-bit unsigned int).
Iterate array backwards (can do forwards as well) and shift the int representation of the respective character accordingly and fit it into the resultant value.
#include <iostream>
#include <cstdint>
using namespace std;
int main() {
char arr[] = {0x00, 0x00, 0x1B, 0x1B}; // just for my testing convenience
uint32_t val = 0;
for (int i = 3; i >= 0; i--) {
uint32_t tmp = arr[i];
int j = 4 - i;
while (--j) {
tmp <<= 8;
}
val |= tmp;
}
cout << val << endl;
}
Upvotes: 1
Reputation: 378
I generally thought you have to store as a char first, then you cast to int during the println().
Upvotes: -1