I am trying to put hex values into a Byte[], Trying to achieve 78,66,1E,B5,4F,E7,67,63
#define BYTE unsigned char
int num = 1;
long long hex[]
{
0x78661EB54FE76763,
};
int main()
{
for (int c = 0; c < num; c++)
{
printf("%llx\n", hex[c]);
unsigned int number = hex[c];
unsigned int ef = number & 0xff;
unsigned int cd = (number >> 8) & 0xff;
unsigned int ab = (number >> 16) & 0xff;
printf("%x", number & 0xff);
BYTE data2[8]{
ef, cd, ab
};
}
}
Update:
Basically I have an array of 30 odd hex values. I am trying to loop through that array called hex[], then for each hex value separate it into 2's ie 78,66,1E,B5,4F,E7,67,63 then add each one into an array of type BYTE which will hold the hex value in 8 pairs so data[0] will have the value of 78 up to data[8] which will have the value of 63, So I can then pass the array of type BYTE to another method for further work
Here is the solution that you want:
#include <stdio.h>
typedef unsigned char BYTE;
int main()
{
int i,j;
long long hex=0x78661EB54FE76763;
BYTE val[8];
for(j=0,i=7; i>=0; i--,j++){
val[j]= (hex>>(i*8))&0xff;
}
printf("Hexadecimal bytes are:\n");
for(j=0;j<8;j++){
printf("%02X ",val[j]);
}
return 0;
}
And the output is:
Hexadecimal bytes are:
78 66 1E B5 4F E7 67 63
Assuming that BYTE is a type
BYTE data2[] = {ef, cd, ab, '\0'};
Use the null terminator to allow printing with "%s" and printf().
Of course, you can add the rest of the bytes.
This is a pretty simple task to accomplish all you need is the initialization values that you have given. long long hex[] = { 0x78661EB54FE76763 };
Next, you need a char pointer that is pointing to the hex array
unsigned char* pByte = (unsigned char*)hex; // Point to the first element in hex array
Then create an 8 byte buffer and clear it with memset:
unsigned char byteArray[8];
memset(byteArray, 0, sizeof(byteArray));
All you need to do now is dereference your char pointer and place the value into your 8 byte buffer.
// Loop through the hex array and assign the current byte
// the byte pointer is pointing to then increment the byte pointer
// to look at the next value.
// This for loop is for a system that is little endian (i.e. win32)
for (int i = 7; i >= 0; i--)
{
byteArray[i] = *pByte;
pByte++;
}
Note: Since I ran this with Visual Studio 2015 everything is little endian. This is why the first for loop is written the way it is.
See below for the full program listing I wrote & tested below demonstrating this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
long long hex[] = { 0x78661EB54FE76763 }; // Value of an element
unsigned char* pByte = (unsigned char*)hex; // Assign a char pointer to point to the first element in hex array
unsigned char byteArray[8]; // This is the byte buffer that will be populated from the hex array
memset(byteArray, 0, sizeof(byteArray)); // Clear out the memory of byte array before filling in the indices
// Loop through the hex array and assign the current byte
// the byte pointer is pointing to then increment the byte pointer
// to look at the next value.
// This for loop is for a system that is little endian (i.e. win32)
for (int i = 7; i >= 0; i--)
{
byteArray[i] = *pByte; // Dereference the pointer and assign value to buffer
pByte++; // Point to the next byte
}
// Print the byte array
for(int i = 0; i < 8; i++)
{
printf("The value of element %i is: %X\n", i, byteArray[i]);
}
printf("Press any key to continue..."); // Hold the console window open
getchar();
return 0;
}
Related
OK...this seems like a fairly easy problem but I can't figure out what is going on here. I have the following code to convert an integer to a byte array and test the output:
#include <stdio.h>
void int2bytearray(char *byte_array, int size, int num)
{
for (int i = 0; i < size; i++)
{
byte_array[i] = (num >> 8*i) & 0xFF;
}
}
int main()
{
int test_int = 657850;
int size = sizeof(int);
printf("Size is %d\n", size);
printf("Size of char is %d\n", (int)sizeof(char));
char test_array[size];
printf("Size of first entry %d\n", (int)sizeof(test_array[0]));
int2bytearray(test_array, size, test_int);
for (int i=0; i < size; i++)
{
printf("%#02x", test_array[i]);
}
printf("\nFirst byte is %#.2X", test_array[0]);
return 0;
}
I expect main to return an array of bytes, but the first "byte" appears to be a 32 bit integer.
Unfortunately, I get the following output:
Size is 4
Size of char is 1
Size of first entry 1
0xffffffba0x90xa00
First byte is 0XFFFFFFBA
Can someone tell me why this first byte is printing out as 0XFFFFFFBA? Why is it a 32-bit integer and not a byte as defined?
The problem is related both to the type being used and how you're printing the values.
The first element in the array has value 0xBA which as a signed char is -70 in decimal. When this value is passed to printf it is converted to type int, so now you have a 32 bit value of -70 whose representation is 0XFFFFFFBA you then print it using %X it which prints an unsigned int in hex.
There are two ways to fix this.
First, change the type of test_array to unsigned char. Then the values stored will be positive and print correctly. The other option is to use %hhX as the format specifier which states to print the value as an unsigned char which will print the proper number of digits.
I am writing some code for an Atmel micro-controller. I am getting some data via Uart, and I store these hex values into an array.
Suppose the elements of the array are: 1F, 29, and 3C.
I want to have one hex number like 0x1F293C, and convert it to a decimal number. So, I want to get “2042172” at the end.
The array could have n elements, so I need a general solution.
Thank you.
sprintf(buffer, "%d", (((unsigned)array[0])<<16)+(((unsigned)array[1])<<8)+(unsigned)array[2];
this will write the hex values in array to buffer as readable string in decimal representation.
assuming sizeof(int)=4
If you have a array of characters like "0x1F293C" and want to convert it to int try this code:
char receivedByte[] = "0x1F293C";
char *p;
int intNumber = strtol(receivedByte, &p, 16);
printf("The received number is: %ld.\n", intNumber);
If data is declared as stated in the comments (char data[]={0x1F, 0x29, 0x3C}), you can run this program.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char receivedByte[9], *p;
char data[] = { 0x1F, 0x29, 0x3C };
sprintf(receivedByte, "0x%X%X%X", data[0], data[1], data[2]);
int intNumber = strtol(receivedByte, &p, 16);
printf("The received number is: %ld.\n", intNumber);
return 0;
}
If the input consists of n bytes and are stored starting from a pointer array, you can add the values up in the order you "received" them - i.e., in the order they are written in the array.
unsigned int convertToDecimal (unsigned char *array, int n)
{
unsigned int result = 0;
while (n--)
{
result <<= 8;
result += *array;
array++;
}
return result;
}
Note that your sample input contains 3 bytes and you want a "general solution for n bytes", and so you may run out of space really fast. This function will only work for 0..4 bytes. If you need more bytes, you can switch to long long (8 bytes, currently).
For longer sequences than that you need to switch to a BigNum library.
#include <stdio.h>
int main(){
char data[] = {0x1F, 0x29, 0x3C};
int i, size = sizeof(data);
unsigned value = 0;
for(i=0;i<size;++i)
value = value * 256 + (unsigned char)data[i];
printf("0x%X %d\n", value, (int)value);
return 0;
}
I have code snippet as Below
unsigned char p = 0;
unsigned char t[4] = {'a','b','c','d'};
unsigned int m = 0;
for(p=0;p<4;p++)
{
m |= t[p];
printf("%c",m);
m = m << 2;
}
Can anybody help me in solving this. consider i have an ascii value abcd stored in an array t[]. I want to store the same value in 'm'. m is my unsigned int variable . which stores the major number. when i copy the array into m & print m . m should print abcd. can anybody state their logic.
As I understand you, you want to encode the 4 characters into a single int.
Your bit shifting is not correct. You need to shift by 8 bits rather than 2. You also need to perform the shifting before the bitwise or. Otherwise you shift too far.
And it makes more sense, in my view, to print the character rather than m.
#include <stdio.h>
int main(void)
{
const unsigned char t[4] = {'a','b','c','d'};
unsigned int m = 0;
for(int p=0;p<4;p++)
{
m = (m << 8) | t[p];
printf("%c", t[p]);
}
printf("\n%x", m);
return 0;
}
Why not just look at the t array as an unsigned int?:
unsigned int m = *(unsigned int*)t;
Or you could use an union for nice access to the same memory block in two different ways, which I think is better than shifting bits manually.
Below is an union example. With unions, both the t char array and the unsigned int are stored in the same memory blob. You get a nice interface to each, and it lets the compiler do the bit shifting (more portable, I guess):
#include <stdio.h>
typedef union {
unsigned char t[4];
unsigned int m;
} blob;
int main()
{
blob b;
b.t[0]='a';
b.t[1]='b';
b.t[2]='c';
b.t[3]='d';
unsigned int m=b.m; /* m holds the value of blob b */
printf("%u\n",m); /* this is the t array looked at as if it were an unsignd int */
unsigned int n=m; /* copy the unsigned int to another one */
blob c;
c.m=n; /* copy that to a different blob */
int i;
for(i=0;i<4;i++)
printf("%c\n",c.t[i]); /* even after copying it as an int, you can still look at it as a char array, if you put it into the blob union -- no manual bit manipulation*/
printf("%lu\n", sizeof(c)); /* the blob has the bytesize of an int */
return 0;
}
Simply assign t[p] to m.
m = t[p];
this will implicitly promote char to unsigned int.
unsigned char p = 0;
unsigned char t[4] = {'a','b','c','d'};
unsigned int m = 0;
for(p=0;p<4;p++)
{
m = t[p];
printf("%c",m);
}
I need some help in cutting a string into a pair of characters and then converting it to HEX format.
eg. char *ADDRESS = "0011AABB";
I want the above address to be split "00", "11", "AA" and "BB" and after that is split converting it to 0x00, 0x11, 0xAA and 0xBB which will be stored in an unsigned char.
Thanks
You suggest that your address-strings are of type char *, but I assume you
want a solution that gaurantees not to trash them, i.e. one that takes them
as type char const *.
I assume also that the addresses they can represent are 32-bit, as per the
example char *ADDRESS = "0011AABB".
In that case a solution that does exactly what you ask for in an obvious
way is:
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define ADDRESS_BYTES 4 // Bytes in an address
/* Convert a hex numeral encoding an address to the unsigned chars that it
encodes
`addr_str` - in: a hex numeral encoding an address
`bytes` - out: The unsigned char bytes of the address, high-byte first.
return - The number of bytes output: ADDRESS_BYTES if `addr_str` is a
valid hex numeral, otherwise 0.
*/
unsigned address_bytes(char const *addr_str, unsigned char bytes[ADDRESS_BYTES])
{
char buf[3] = {0}; // 3-bytes of 0-filled working space.
char *endp;
unsigned i = 0;
unsigned j = 0;
assert(strlen(addr_str) == 2 * ADDRESS_BYTES); // Insist on 8-char string
for ( ;i < 2 * ADDRESS_BYTES; ++j) { // Take chars 2 at a time
buf[i % 2] = addr_str[i]; ++i; // Next char to buf[0]
buf[i % 2] = addr_str[i]; ++i; // Next + 1 char to buf[1]
// Convert buffer from hex numeral to unsigned char in next byte.
bytes[j] = (unsigned char)strtoul(buf,&endp,16);
if (*endp) { // Check for invalid hex.
return 0; // Failure
}
}
return j; // = 4
}
// A test program...
#include <stdio.h>
int main(void)
{
unsigned char bytes[ADDRESS_BYTES];
char const * address = "0011AABB";
unsigned done_bytes = address_bytes(address,bytes);
printf("The %d valid address bytes are (hex):",done_bytes);
unsigned i = 0;
for ( ;i < done_bytes; ++i) {
printf(" %02x",(unsigned)bytes[i]);
}
putchar('\n');
return 0;
}
However, exactly what you ask for is not an efficient solution.
You can accomplish your goal by simply converting an 8-char hex-numeral encoding
a 32-bit address into the encoded 32-bit unsigned integer, and then getting the
4 unsigned char bytes that compose this unsigned integer in high-byte-first order.
Converting the hex numeral to a uint32_t can be done with a single call to
strtoul. Then getting the unsigned char bytes of this uint32_t in
high-byte-first order is simply a matter of knowing whether that uint32_t is
big-endian or little-endian. So here is a better solution:
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
unsigned address_bytes(char const *address, unsigned char bytes[ADDRESS_BYTES])
{
union {
uint32_t i;
char c[ADDRESS_BYTES];
} endian_tester = {0x01020304};
int big_endian = endian_tester.c[0] == 1;
uint32_t addr = 1;
char *endp;
assert(strlen(address) == 2 * ADDRESS_BYTES);
addr = (uint32_t)strtoul(address,&endp,16);
if (*endp) {
return 0;
}
endp = (char *)&addr;
if (big_endian) {
// The least significant byte is highest in memory
bytes[0] = endp[0];
bytes[1] = endp[1];
bytes[2] = endp[2];
bytes[3] = endp[3];
} else {
// The least significant byte is lowest in memory
bytes[0] = endp[3];
bytes[1] = endp[2];
bytes[2] = endp[1];
bytes[3] = endp[0];
}
return ADDRESS_BYTES;
}
And if you are able and willing to make the non-portable assumption that
the address-strings are encoded in ASCII, then you could avoid calling
strtoul entirely and compute the output bytes directly from the input
chars, using the characters' positions in the ASCII collating sequence
to get the unsigned char values that they encode:
#include <assert.h>
#include <string.h>
#include <ctype.h>
unsigned address_bytes(char const *address, unsigned char bytes[ADDRESS_BYTES])
{
unsigned i = 0;
unsigned j = 0;
assert(strlen(address) == 2 * ADDRESS_BYTES);
for ( ; i < 2 * ADDRESS_BYTES; ++i,++j) {
// First character of a pair..
if (isdigit(address[i])) {
// A decimal digit encodes its ASCII value - '0'
bytes[j] = address[i] - '0';
} else if (isxdigit(address[i])) {
// A hex digit encodes 10 + its ASCII value - 'A'
bytes[j] = 10 + address[i] - 'A';
} else {
return 0; // Invalid hex
}
++i; // Second character of a pair...
bytes[j] <<= 4; // Shift the 1st character's value 1 nibble high
// OR the 2nd character's value into the low nibble of the byte...
if (isdigit(address[i])) {
bytes[j] |= address[i] - '0';
} else if (isxdigit(address[i])) {
bytes[j] |= 10 + address[i] - 'A';
} else {
return 0; // Invalid hex
}
}
return ADDRESS_BYTES;
}
The last might be the fastest if that matters.
Built and tested with GCC 4.7.2 and clang 3.2
I'm working on a C project and I have some instructions of type:
add $1 $2 $3
So I'm reading the line as a string, parsing through it and have a corresponding integer for add, say - 2. Could anyone please tell me how I could convert this to binary in order to write it to a file?
The registers are 5 bits and the operation is 6 bits. The total will be 32 (the last 10 bits are unused).
So the registers are stored in say op[] = "2", char r1[] = "1", char r2[] = "2" etc (note that register number can be as high as 31). Could anyone give me an example for a function that would convert this to binary in the format 000010 00001 00010 00011 0000000000
The easiest way will be using a bit field:
struct code {
unsigned opcode : 6;
unisgned operand1 : 5;
unisgned operand2 : 5;
unisgned operand2 : 5;
} test_code;
Now you can simply assign to the different members:
test_code.opcode = 0x02;
test_code.operator1 = 0x01;
test_code.operator2 = 0x02;
test_code.operator3 = 0x03;
atoi(op) will give you 2, so you can just string it together
As far as putting it into that structure you want, just create a structure that has bitfields in it and place it in a union with a 32 bit unsigned integer, and you can take the value directly.
Quick pseudo code
const char* int32_to_bin(int32_t value) {
int pos = 0;
char output[33];
while(value > 0) {
if (value & 1) output[pos++] = '1';
else output[pos++] = '0';
value >>= 1;
}
output[pos] = 0;
return output;
}
What you're asking is a C question but you tag as objective-c so I'll cover both.
C:
These variables such as op[].. are really defined as like char op[..] (not sure if your length), which are C strings of course.
So the operation is 6 bit and each register is 5 bits, that's 15 + 6 = 21 bit word. I'll assume the top 11 bits are zeroes.
What you need are 4 more variables that are integers:
int opint; int r0int; int r1int; int r2int;
You want the integer value of those strings to go in to those integers. You can use atoi() to achieve this, such as opint = atoi(op);
Now that you've got your integers derived from strings, you need to create the 32 bit word. The easiest way to do this is to first create one integer that holds those bits in the right place. You can do it (assuming 32 bit integers) like this:
int word = 0;
word |= ((opint & 0x3f) << (21 - 6))) |
(r0int & 0x1f) << (21 - 11)) |
(r1int & 0x1f) << (21 - 16))
(r2int & 0x1f));
Where the << is shifting in to place. After this, you should have the word integer properly formed. Next, just turn it in to a binary representation (if that's even necessary? Not sure on your application)
Objective-C
The only difference is that I assume those strings start as NSString *op; etc. In this case, get the integers by opint = [op intValue];, then form the word as I describe.
This code will convert a string to binary
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char* stringToBinary(char* s) ;
void binchar(char output[], char character);
void itoa(int value, char* str, int base);
int main(int argc, char const *argv[])
{
printf("%s\n", stringToBinary("asdf") );
}
char* stringToBinary(char* s) {
if(s == NULL) return 0; /* no input string */
size_t len = strlen(s);
char *binary = malloc(len*8 + 1); // each char is one byte (8 bits) and + 1 at the end for null terminator
int i =0;
char output[9];
for(i=0; i< len; i++){
binchar(output, s[i]);
strcat(binary,output);
}
return binary;
}
void binchar(char output[], char character)
{
//char output[9];
itoa(character, output, 2);
}
// since GCC is not fully supporting itoa function here is its implementaion
// itoa implementation is copied from here http://www.strudel.org.uk/itoa/
void itoa(int value, char* str, int base) {
static char num[] = "0123456789abcdefghijklmnopqrstuvwxyz";
char* wstr=str;
int sign;
// Validate base
if (base<2 || base>35){ *wstr='\0'; return; }
// Take care of sign
if ((sign=value) < 0) value = -value;
// Conversion. Number is reversed.
do *wstr++ = num[value%base]; while(value/=base);
if(sign<0) *wstr++='-';
*wstr='\0';
// Reverse string
void strreverse(char* begin, char* end);
strreverse(str,wstr-1);
}
void strreverse(char* begin, char* end) {
char aux;
while(end>begin)
aux=*end, *end--=*begin, *begin++=aux;
}