I am trying to convert a character to its binary representation (so character --> ascii hex --> binary).
I know to do that I need to shift and AND. However, my code is not working for some reason.
Here is what I have. *temp points to an index in a C string.
char c;
int j;
for (j = i-1; j >= ptrPos; j--) {
char x = *temp;
c = (x >> i) & 1;
printf("%d\n", c);
temp--;
}
We show up two functions that prints a SINGLE character to binary.
void printbinchar(char character)
{
char output[9];
itoa(character, output, 2);
printf("%s\n", output);
}
printbinchar(10) will write into the console
1010
itoa is a library function that converts a single integer value to a string with the specified base.
For example... itoa(1341, output, 10) will write in output string "1341".
And of course itoa(9, output, 2) will write in the output string "1001".
The next function will print into the standard output the full binary representation of a character, that is, it will print all 8 bits, also if the higher bits are zero.
void printbincharpad(char c)
{
for (int i = 7; i >= 0; --i)
{
putchar( (c & (1 << i)) ? '1' : '0' );
}
putchar('\n');
}
printbincharpad(10) will write into the console
00001010
Now i present a function that prints out an entire string (without last null character).
void printstringasbinary(char* s)
{
// A small 9 characters buffer we use to perform the conversion
char output[9];
// Until the first character pointed by s is not a null character
// that indicates end of string...
while (*s)
{
// Convert the first character of the string to binary using itoa.
// Characters in c are just 8 bit integers, at least, in noawdays computers.
itoa(*s, output, 2);
// print out our string and let's write a new line.
puts(output);
// we advance our string by one character,
// If our original string was "ABC" now we are pointing at "BC".
++s;
}
}
Consider however that itoa don't adds padding zeroes, so printstringasbinary("AB1") will print something like:
1000001
1000010
110001
unsigned char c;
for( int i = 7; i >= 0; i-- ) {
printf( "%d", ( c >> i ) & 1 ? 1 : 0 );
}
printf("\n");
Explanation:
With every iteration, the most significant bit is being read from the byte by shifting it and binary comparing with 1.
For example, let's assume that input value is 128, what binary translates to 1000 0000.
Shifting it by 7 will give 0000 0001, so it concludes that the most significant bit was 1. 0000 0001 & 1 = 1. That's the first bit to print in the console. Next iterations will result in 0 ... 0.
Your code is very vague and not understandable, but I can provide you with an alternative.
First of all, if you want temp to go through the whole string, you can do something like this:
char *temp;
for (temp = your_string; *temp; ++temp)
/* do something with *temp */
The term *temp as the for condition simply checks whether you have reached the end of the string or not. If you have, *temp will be '\0' (NUL) and the for ends.
Now, inside the for, you want to find the bits that compose *temp. Let's say we print the bits:
for (as above)
{
int bit_index;
for (bit_index = 7; bit_index >= 0; --bit_index)
{
int bit = *temp >> bit_index & 1;
printf("%d", bit);
}
printf("\n");
}
To make it a bit more generic, that is to convert any type to bits, you can change the bit_index = 7 to bit_index = sizeof(*temp)*8-1
Related
I have a char array which contains ASCII characters. I need to know how to get the hex value of each character and save it in a uint8_t array.
E.g. if I have
array[5] = "ABCDE"
The output should be
output[5] = {0x41, 0x42, 0x43, 0x44, 0x45}
I tried using strtol but didn't work.
for(unsigned i = 0; i < 32; i++) {
message[i] = (uint8_t)strtol(&incoming_message[i], NULL, 16);
}
Output:
A 0 0 0 0 0 0 0 0 0 F 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Update: This is for a program I'm writing for a Cortex-M0+ processor. I'm not just viewing incoming data, I'm processing this data in the next step. Therefore, no use of printf
First of all, strtol like all other string functions expects a null-terminated byte string, not single characters.
Secondly, the characters encoded value is the actual value of the elements in your string. If you print the decimal value 65 (for example) using the correct format specifier, then the character A will be printed:
printf("%c\n", 65); // Will print an A
Similarly, printing the character 'A' as a decimal integer will print the value 65:
printf("%d\n", 'A'); // Will print the value 65
So all you need to do is to print the values in your array in the correct format.
Furthermore... All values on computers the last few decades are stored in binary. All of them.
Decimal, octal or hexadecimal are just how you present the values. Storing 0x41, 61, 0101 or 0b01000001 (for compilers with binary notation extension) doesn't matter since in the end it will be the binary value that is stored. If you want to show a value as hexadecimal to a user through some output, you have to format the binary value as such when printing or writing it.
Talking C a char is the smallest integer value available.
Talking C and ASCII a character literal (like 'A') is just another representation of an int value (65 here).
Talking Math there are other ways to represent the very same value, aside the decimal way (using base 10). One common is using the base of 16, the hexadecimal way.
Putting the above together it proves that:
int i = 'A';
char c = i;
is the same as:
int i = 65;
char c = i;
and the same as:
int i = 0x41;
char c = i;
and the same as:
char c = 'A';
and the same as:
char c = 65;
and the same as:
char c = 0x41;
So
char a[5] = "ABCDE";
in fact already is an integer array of five (small) integers.
If printed using the correct conversion specifier and length modifier you see what you are after.
for (size_t i = 0; i < 5; ++i)
{
printf("%hhx ", a[i]);
}
Output:
41 42 43 44 45
To indicate to the reader this should be taken as hexadecimal values one could prefix the value using the common 0x notation
printf("0x%hhx ", a[i]);
which gave you
0x41 0x42 0x43 0x44 0x45
If you would show this to Pascal guys you perhaps would use
printf("$%hhx ", a[i]);
which gave you
$41 $42 $43 $44 $45
To see the characters themselves just us:
printf("%c ", a[i]);
and get
A B C D E
To see the decimal values use
printf("%d ", a[i]);
and get
65 66 67 68 69
The conclusion is, that it's all just matter of how you represent ("print") the same values (the content of a's elements) . The "conversion" happens when creating the representation of a very same value (via printing and passing the right "instructions"), that is during output only.
As you refer to ASCII only, this implies all value are <128, so you can just plain copy the array's values using either a loop
char src[5] = "ABCDE";
uint8_t dst[5];
for (size_t i = 0 i < 5; ++i)
{
dst[i] = src[i];
}
or by copying the related memory block at once
memcpy(dst, src, 5);
you can convert the value to hexadecimal using the basic algorithm i.e division by 16.
I have created the following function where you can pass the string to be converted and a an array of strings where you will get the response.
void hexCon(char str[],char result[][5]){
int i,check,rem = 0;
char res[20],res2[20];
int len = 0;
char temp;
for(i=0; i < strlen(str) ; i++){
len=0;
check = str[i];
while(check > 0){
rem = check%16;
switch(rem){
case 10:temp='A';break;
case 11:temp='B';break;
case 12:temp='C';break;
case 13:temp='D';break;
case 14:temp='E';break;
case 15:temp='F';break;
default:temp=rem + '0';
}
res[len] = temp;
check = check /16;
len++;
}
reverse(res,len,res2); //reversing the digits
res2[len] = '\0'; //adding null character at the end of string
strcpy(result[i],res2); //copying all data to result array
}
}
where reverse function is :
void reverse(char str[], int size, char rev[])
{
int i=0,j=0;
for(i=size-1 , j=0 ; i >= 0; i-- , j++ ){
rev[j] = str[i];
}
}
you can call it like :
void main(){
char str[]="ABCDE";
char result[strlen(str)][5];
int i;
hexCon(str,result);
for(i =0 ;i < strlen(str); i++){
printf("%s\n",result[i]);
}
}
the algorithm used is explained here :-
https://www.permadi.com/tutorial/numDecToHex/
Hope this helps :)
How can I convert integer value to ASCII characters in C language?
I want to assign characters to array of chars.
char buff[10];
Let's say we have:
int = 93 (HEX: 5D) -> result should be - buff = {']'}
int = 13398 (HEX: 3456) -> result should be buff = {'4', 'V'}
Similar as is done here
I don't need to care about non printable characters. There will be always printable characters.
Just use bit-shifting to get the individual bytes.
Assuming an architecture on which the size of int is 4:
int someInt = ...
uint8_t first = (someInt >> 24);
uint8_t second = (someInt >> 16);
uint8_t third = (someInt >> 8);
uint8_t fourth = someInt;
Now you can just put the resulting bytes into your array. Make sure to check first, second and third to make sure they're not 0 first, and skip them if they are. Make sure to end your array with a null terminator, as required by C strings.
This answer assumes big-endian ordering, since that's what you indicated in your example. If you want little-endian, just reverse the order of the bytes when you put them in the array.
Note that this will turn 5DC into 05 and DC. If you want 5D instead, you should check to see whether the first digit in the original int is 0. You can do this using the & operator, testing the int against 0xf0000000, 0x00f00000, etc. If you find the first digit to be 0, shift the int to the right by 4 bits before extracting the bytes from it.
So, something like this:
void ExtractBytes(int anInt, uint8_t *buf, size_t bufSize) {
// passing an empty buffer to this function would be stupid,
// but hey, doesn't hurt to be idiot-proof
if (bufSize == 0) { return; }
// Get our sizes
const int intSize = sizeof(anInt);
const int digitCount = intSize * 2;
// find first non-zero digit
int firstNonZero = -1;
for (int i = 0; i < digitCount; i++) {
if ((anInt & (0xf << ((digitCount - 1 - i) * 4))) != 0) {
firstNonZero = i;
break;
}
}
if (firstNonZero < 0) {
// empty string; just bail out.
buf[0] = 0;
return;
}
// check whether first non-zero digit is even or odd;
// shift if it's odd
int intToUse = (firstNonZero % 2 != 0) ? (anInt >> 4) : anInt;
// now, just extract our bytes to the buffer
int bufPtr = 0;
for (int i = intSize - 1; i >= 0; i--) {
// shift over the appropriate amount, mask against 0xff
uint8_t byte = (intToUse >> (i * 8));
// If the byte is 0, we can just skip it
if (byte == 0) {
continue;
}
// always check to make sure we don't overflow our buffer.
// if we're on the last byte, make it a null terminator and bail.
if (bufPtr == bufSize - 1) {
buf[bufPtr] = 0;
return;
}
// Copy our byte into the buffer
buf[bufPtr++] = byte;
}
// Now, just terminate our string.
// We can be sure that bufPtr will be less than bufSize,
// since we checked for that in the loop. So:
buf[bufPtr] = 0;
// Aaaaaand we're done
}
Now let's take it for a spin:
uint8_t buf[10];
ExtractBytes(0x41424344, buf, 10);
printf("%s\n", buf);
ExtractBytes(0x4142434, buf, 10);
printf("%s\n", buf);
and the output:
ABCD
ABC
convert integer value to ASCII characters in C language?...
Referring to an ASCII table, the value of ']' in C will always be interpreted as 0x5D, or decimal value 93. While the value of "]" in C will always be interpreted as a NULL terminated char array, i.e., a string representation comprised of the values:
|93|\0|
(As illustrated in This Answer, similar interpretations are valid for all ASCII characters.)
To convert any of the integer (char) values to something that looks like a "]", you can use a string function to convert the char value to a string representation. For example all of these variations will perform that conversion:
char strChar[2] = {0};
sprintf(strChar, "%c", ']');
sprintf(strChar, "%c", 0x5D);
sprintf(strChar, "%c", 93);
and each produce the identical C string: "]".
I want to assign characters to array of chars...
example of how to create an array of char, terminated with a NULL char, such as "ABC...Z":
int i;
char strArray[27] = {0};
for(i=0;i<26;i++)
{
strArray[i] = i+'A';
}
strArray[i] = 0;
printf("Null terminated array of char: %s\n", strArray);
unsigned u = ...;
if (0x10 > u)
exit(EXIT_FAILURE);
while (0x10000 < u) u /= 2;
while (0x1000 > u) u *= 2;
char c[2] = {u / 0x100, u % 0x100);
Here I have created a string and I am storing the binary value of a number in the string.. I want to store the value of the variable num to the string.
i contains the length of the binary number for the given decimal number..suppose the given number is A=6, i contains 3 and i need a string 'result' having '110' which is the binary value of 6.
char* result = (char *)malloc((i)* sizeof(char));
i--;
while(A>=1)
{
num=A%2;
result[i]=num; // here I need to store the value of num in the string
A=A/2;
i--;
}
It appears from the code you've posted is that what you are trying to do is to print a number in binary in a fixed precision. Assuming that's what you want to do, something like
unsigned int mask = 1 << (i - 1);
unsigned int pos = 0;
while (mask != 0) {
result[pos] = (A & mask) == 0 ? '0' : '1';
++pos;
mask >>= 1;
}
result[pos] = 0; //If you need a null terminated string
edge cases left as an exercise for the reader.
I'm not sure specifically what you are asking for. Do you mean the binary representation (i.e. 00001000) of a number written into a string or converting the variable to a string (i.e. 8)? I'll assume you mean the first.
The easiest way to do this is to repeatedly test the least significant bit and shift the value to the right (>>). We can do this in for loop. However you will need to know how many bits you need to read. We can do this with sizeof.
int i = 15;
for (int b = 0; b < sizeof(i); ++b) {
uint8_t bit_value = (i & 0x1);
i >>= 1;
}
So how do we turn this iteration into a string? We need to construct the string in reverse. We know how many bits are needed, so we can create a string buffer accordingly with an extra byte for NULL termination.
char *buffer = calloc(sizeof(i) + 1, sizeof(char));
What this does is allocates memory that is sizeof(i) + 1 elements long where each element is sizeof(char), and then zero's each element. Now lets put the bits into the string.
for (int b = 0; b < sizeof(i); ++b) {
uint8_t bit_value = (i & 0x1);
size_t offset = sizeof(i) - 1 - b;
buffer[offset] = '0' + bit_value;
i >>= 1;
}
So what's happening here? In each pass we're calculating the offset in the buffer that we should be writing a value to, and then we're adding the ASCII value of 0 to bit_value as we write it into the buffer.
This code is untested and may have some issues, but that is left as an exercise to the reader. If you have any questions, let me know!
here is the whole code. It is supposed to work fine.
int i=0;
int A;//supposed entered by user
//calculating the value of i
while(A!=0)
{
A=A/2;
i++;
}
char* result=(char *)malloc(sizeof(char)*i);
i--;
while(A!=0)
{
result[i]='0'+(A%2);
A=A/2;
i--;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
char *numToBinStr(int num){
static char bin[sizeof(int) * CHAR_BIT + 1];
char *p = &bin[sizeof(int) * CHAR_BIT];//p point to end
unsigned A = (unsigned)num;
do {
*--p = '0' + (A & 1);
A >>= 1;
}while(A > 0);//do-while for case value of A is 0
return p;
}
int main(void){
printf("%s\n", numToBinStr(6));
//To duplicate, if necessary
//char *bin = strdup(numToBinStr(6));
char *result = numToBinStr(6);
char *bin = malloc(strlen(result) + 1);
strcpy(bin, result);
printf("%s\n", bin);
free(bin);
return 0;
}
You could use these functions in <stdlib.h>:
itoa(); or sprintf()
The second link has some examples as well.
I have to convert a given binary input (e.g. 1101) to decimal, but the input isn't a string array or an integer (the passed argument is const char *binstr). How am I supposed to access each individual digit of the binary number so I can do pow(x,y) on each and add them together to get the decimal number?
const char * usually refers to a C string. You can just use strtol(3):
int x = strtol(binstr, NULL, 2);
You could try with this program which converts from Binary to Decimal
char *binstr = "1011011";
int num = 0, sum = 0, ctr = 0;
ctr = strlen(binstr) - 1;
do{
sum += ((binstr[ctr] & 0x1) << num);
ctr--;
num ++;
}while(ctr >= 0);
binstr[0];
binstr[1];
binstr[2];
etc
or you can do it through a pointer
char* s = binstr;
unsigned long x =0;
while(*s) { x = x << 1; x |= (*s == '1' ? 1:0); s++;}
printf("the decimal of %s is %ul", binstr, x);
You've made a c string and you can get each character the way similar to arrays:
input[i]
Here's an example of splitting the binary string into individual bits (characters) and printing them out: http://cfiddle.net/wYtKJv
You can use loops:
while(i<100){
if(binstr[i]== '\0'){
break;
}
printf("First Bit:\n%c\n\n",binstr[i]);
i++;
}
Since C-strings are null terminated you can check to see if a character if we hit is '\0' to break the loop.
In the loop you can also convert the chars to ints and store them someplace (array probably) where you can access them for calculations.
I have the following string:
char * strIn = "f2";
When I look at strIn[0] I would like to get 1111 instead of 'f'.
How do i do it?
Thanks
You mean a hex string to binary conversion?
strtol with a base of 16 should do the trick
...Someone said earlier
and f in binary would be 11001100
All I can say is wow... no, F in binary equals 1111 (15 decimal)
If I understood your question correctly, you want to get the binary value for any ascii character... ie.
When I look at strIn[0] I would like
to get 1111 instead of 'f'.
So... here is a little function that will do that...
int ConvertHexAsciiValue(char c)
{
if(isalpha(c))
{
char r = tolower(c);
if(r > 'f')
{
// - Handle error here - character is not base 16
return 0;
}
int nIndex = (int)('a' - r);
nIndex = -nIndex;
nIndex += 10;
return nIndex;
}
else if(isdigit(c))
{
int nIndex = c - '0';
return nIndex;
}
// Handle error here - character is not A-F or 0-9
return 0;
}
If I didn't understand you correctly, you should know that you cannot read a string "1111" for a character strIn[0]. You can however, get a binary value for each character (interpreted as a hexidecimal value) using the function I provided...
for(int x = 0; x < strlen(strIn); x++)
{
int val = ConvertHexAsciiValue(strIn[x]);
printf("Value %d: %d\n", x, val);
}
If strIn were set to "f2", this code would produce the following output on the console
Value 0: 15
Value 1: 2
To get the binary code one must take the decimal number in question, take it and divide it by two repeatedly, save the remainder (which will become the binary number), save the whole number, divide by two, and repeat the whole process until 0 is reached.
Heres a small application I had in my collection that converts a string into binary.
/********************************************************/
/* Binary converter */
/* By Matt Fowler */
/* philosopher150#yahoo.com */
/* converts text into binary using the division method */
/* through ASCII code */
/*compiled with the Dev-C++ compiler (www.bloodshed.net)*/
/********************************************************/
#include <iostream>
using namespace std;
#include <cstring>
#include <cstdlib>
char *entry, letter, choice[2];
int ascii, len, binary[8], total;
void prog();
int main()
{
prog();
return 0;
}
void prog()
{
entry = new char[501];
/* entry should be dynamic, otherwise a new string entry of 501 chars would be created each time function is called! Talk about memory hog! */
cout<<"Enter string to convert (up to 500 chars): ";
cin.getline(entry, 500);
len = strlen(entry); /* get the number of characters in entry. */
/* this loop is executed for each letter in the string. */
for(int i = 0; i<len; i++)
{
total = 0;
letter = entry[i]; /* store the first letter */
ascii = letter; /* put that letter into an int, so we can see its ASCII number */
while(ascii>0) /* This while loop converts the ASCII # into binary, stores it backwards into the binary array. */
{
/* To get the binary code one must take the decimal number in
question, take it and divide it by two repeatedly, save
the remainder (which will become the binary number), save
the whole number, divide by two, and repeat the whole
process until 0 is reached. This if-else statement serves
this functionality, by getting the remainder of the ascii
code, storing it in the array and then dividing the int
ascii by two */
if((ascii%2)==0)
{
binary[total] = 0;
ascii = ascii/2;
total++; /* increasing by one each time will yeild the
number of numbers in the array. */
}
else
{
binary[total] = 1;
ascii = ascii/2;
total++;
}
}
total--; /* due to data type factors, the program will actually
add a 0 at the end of the array that is not supposed
to be there, decrementing total will solve this
problem, as that 0 will not be displayed. */
/* this while loop displays the binary code for that letter. */
while(total>=0)
{
cout<<binary[total];
total--;
}
}
delete[] entry; /* free up the memory used by entry */
cout<<endl<<"Do again(1 = yes, 2= no)?: ";
cin.getline(choice,3);
if(choice[0] == '1')
prog(); /* program is recursive, it calls itself. It's kinda
like a function loop of sorts. */
else
exit(0); /* quits the program */
}