Our school gave us an assignment and in some part of that assignment we are supposed to take a hexadecimal input then convert it to binary. But the problem is that using arrays are not permitted. When using an array to store the hexadecimal string I can easily convert it to binary but is there anyway to store it without using arrays?
Your task seems to be:
Convert input data entered as hexadecimal values to a stream of binary digits.
You can just read the input ne byte at a time and convert any hexadecimal character to the corresponding binary digits.
There are many different ways to approach this problem, here is an implementation with a switch statement.
#include <stdio.h>
int main() {
int c;
while ((c = getchar()) != EOF) {
switch (c) {
case '0': fputs("0000", stdout); break;
case '1': fputs("0001", stdout); break;
case '2': fputs("0010", stdout); break;
case '3': fputs("0011", stdout); break;
case '4': fputs("0100", stdout); break;
case '5': fputs("0101", stdout); break;
case '6': fputs("0110", stdout); break;
case '7': fputs("0111", stdout); break;
case '8': fputs("1000", stdout); break;
case '9': fputs("1001", stdout); break;
case 'A':
case 'a': fputs("1010", stdout); break;
case 'B':
case 'b': fputs("1011", stdout); break;
case 'C':
case 'c': fputs("1100", stdout); break;
case 'D':
case 'd': fputs("1101", stdout); break;
case 'E':
case 'e': fputs("1110", stdout); break;
case 'F':
case 'f': fputs("1111", stdout); break;
case '\n':
case ' ': putchar(c); break;
default: break;
}
}
return 0;
}
If you just need to read a value encoded as a hexadecimal string and store it into a variable, scanf() is a simple solution:
#include <stdio.h>
void print_binary(unsigned int x) {
if (x > 1) {
print_binary(x >> 1);
}
putchar('0' + (x & 1));
}
int main(void) {
unsigned int value;
if (scanf("%x", &value) == 1) {
print_binary(value);
putchar('\n');
}
return 0;
}
Related
So i was trying to type this program but its keep failing , can anyone help with me ?
Write a function to return a nonzero if the character is a vowel(a, e, i, o, u – upper or lower case), or zero if it is not a vowel. Test the function in a program that allows input of string and a single character output of the characters in the string with the vowels enclosed with angle brackets as shown.
Sample Output
Enter a name: Aloysius
Result: [A]l[o]ys[i][u]s
Note: Bold text above is the input
#include <stdio.h>//Question 1
#include <string.h>
int check_vowel();
char string[300];
int idx;
int length,status;
int main(void) {
printf("Enter a word: ");;
scanf("%s",string);
length=strlen(string)-1;
for(idx=0;idx<=length;idx++)
{
status=check_vowel();
if(status==1)
printf("<%c>",string[idx]);
else
printf("%c",string[idx]);
}
return 0;
}
int check_vowel()
{
length=strlen(string)-1;
for(idx=0;idx<=length;idx++)
{
switch(string[idx])
{
case 'A': return 1; break;
case 'a': return 1; break;
case 'e': return 1; break;
case 'E': return 1; break;
case 'I': return 1; break;
case 'i': return 1; break;
case 'o': return 1; break;
case 'O': return 1; break;
case 'u': return 1; break;
case 'U': return 1; break;
}
}
return 0;
}
Remove the for loop from check_vowel. Have it take a single argument, a char:
int check_vowel(char c)
{
int is_vowel;
switch(c)
{
case 'a':
case 'A':
case 'e':
case 'E':
case 'i':
case 'I':
case 'o':
case 'O':
case 'u':
case 'U':
is_vowel = 1;
break;
default:
is_vowel = 0;
break;
}
return is_vowel;
}
Call check_vowel from main in a for loop for every char in string:
for(idx = 0; idx <= strlen(string); idx++)
{
status = check_vowel(string[idx]);
...
}
how to write a program to check whether there is vowel, if yes , make the vowel character with two angle bracket like <A> <E> <i> ..... etc . if without vowel leave it , so the display should look like this <A> l <o> y s <i> <u> s. The function should return a nonzero if the character is a vowel(a, e, i, o, u – upper or lower case), or zero if it is not a vowel
The function you created will check if the string contains any vowel.
I have already a function that convert hex char(input) to binary char(output). it works perfect, for small amount of data(input length).But when the input is too big, it stuck/not working. May be strcat take too much time. Is there some alternate solution, So i can convert big hex input characters into equivalent binary.
My function is:
void fun_hex_ch_2bin(int len_hex_str,uint8_t *hex,uint8_t *bin){
/* Extract first digit and find binary of each hex digit */
int i=0,j=0;
char array_hex[16]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
uint8_t *new_hex=malloc(len_hex_str*2);
char hex_char1,hex_char2;
j=0;
for(i=0;i<len_hex_str;i++)
{
hex_char1=array_hex[hex[i]&0x0f];
hex_char2=array_hex[(hex[i]>>4)&0x0f];
//printf("%c %c\n",hex_char1,hex_char2);
new_hex[j]=hex_char2;
new_hex[j+1]=hex_char1;
j=j+2;
}
for(i=0; i<len_hex_str*2; i++)
{
switch(new_hex[i])
{
case '0':
strcat(bin, "0000");
break;
case '1':
strcat(bin, "0001");
break;
case '2':
strcat(bin, "0010");
break;
case '3':
strcat(bin, "0011");
break;
case '4':
strcat(bin, "0100");
break;
case '5':
strcat(bin, "0101");
break;
case '6':
strcat(bin, "0110");
break;
case '7':
strcat(bin, "0111");
break;
case '8':
strcat(bin, "1000");
break;
case '9':
strcat(bin, "1001");
break;
case 'a':
case 'A':
strcat(bin, "1010");
break;
case 'b':
case 'B':
strcat(bin, "1011");
break;
case 'c':
case 'C':
strcat(bin, "1100");
break;
case 'd':
case 'D':
strcat(bin, "1101");
break;
case 'e':
case 'E':
strcat(bin, "1110");
break;
case 'f':
case 'F':
strcat(bin, "1111");
break;
default:
printf("Invalid hexadecimal input.");
}
}
}
Just use sprintf() instead of strcat()
char *bin; // points to a long enough buffer
int binlen = 0;
binlen += sprintf(bin + binlen, "something"); // strcat(bin, "something");
binlen += sprintf(bin + binlen, "otherthing"); // strcat(bin, "otherthing");
binlen += sprintf(bin + binlen, "foobar"); // strcat(bin, "foobar");
//...
// you can even do
binlen += sprintf(bin + binlen, "%.2f", 2.71828); // strcat(bin, "2.72");
16 is a power of 2 so converting it to binary is pretty simple.
Each hex digit corresponds to exactly 4 binary digits - and you can rely on this fact.
As a first step you need to convert the input characters from ASCII to numeric values.
That's easily done in one pass over the input hex string and subtracting 48 if the character is between '0' and '9' or subtracting 88 if the character is between 'a' and 'f' (take a look at the ASCII table if need an explanation on why).
After that the conversion is straightforward - go over the hex array and for each hex value take a look at the last bit and proceed to the next bit exactly 4 times, move to the next hex value and repeat the procedure.
Something like this:
int i = 0, j = 0;
while(i < len_hex_str)
{
bin[j++]=hex[i] & 1;
hex[i] >>= 1;
if(j % 4 == 0) i++;
}
And since you seem to be in need to have it ASCII representation, just pass over the output string and add 48 to each digit.
How can i speed up hexadecimal characters conversion to binary characters (?)
May be strcat take too much time.
Yes. Each call to strcat() takes longer and longer time as code does not take advantage of data already converted.
strcat() take n time to traverse the first characters.
1st strcat call, n = 0
2st strcat call, n = 8
3rd strcat call, n = 16
4th strcat call, n = 24
ith strcat call, n = 8*(i-1)
See how the sum (0+8+16+24+...) goes up by order of i*i as i increases?
Note that the first call to strcat(bin, ...) is suspect as bin[0] is not certainly a null character - something required when concatenating to a string.
Is there some alternate solution (?)
I recommend a re-write. Directly read from hex as binary and skip the in-between conversion to hexadecimal.
void fun_hex_ch_2bin(int len_hex_str, uint8_t *hex, uint8_t *bin) {
while (len_hex_str > 0) {
len_hex_str--;
// Start with the MSBit
for (uint8_t mask = 0x80; mask; mask >>=1) {
*bin++ = mask & *hex ? '1' : '0';
}
hex++;
}
// Append a null character as `bin` is to point to a _string_.
*bin = '\0';
}
I'd expect bin, as a string to be char* and not unit8_t *.
Part of my project, where we have to take an input file with hex numbers and convert them to MIPS code, I want to convert the hex into binary so it'd be easier for me to convert it into MIPS. However, when I run the code, it crashes and quits when it reaches the part where it calls the converter function. GDB says its a critical error c0000374. How do I fix this?
I have tried giving the target string more space and it doesn't seem to have any effect. I have also tried using malloc to no avail.
char* convertBinary (int hex)
{
char* hexdec = calloc(9, sizeof(char));
char* bin = calloc(SIZE+1, sizeof(char));
snprintf(hexdec, SIZE, "%08X", hex);
long int i;
for (i = 0; hexdec[i]; ++i)
{
switch (hexdec[i])
{
case '0':
strcat(bin, "0000");
break;
case '1':
strcat(bin, "0001");
break;
case '2':
strcat(bin, "0010");
break;
case '3':
strcat(bin, "0011");
break;
case '4':
strcat(bin, "0100");
break;
case '5':
strcat(bin, "0101");
break;
case '6':
strcat(bin, "0110");
break;
case '7':
strcat(bin, "0111");
break;
case '8':
strcat(bin, "1000");
break;
case '9':
strcat(bin, "1001");
break;
case 'A':
case 'a':
strcat(bin, "1010");
break;
case 'B':
case 'b':
strcat(bin, "1011");
break;
case 'C':
case 'c':
strcat(bin, "1100");
break;
case 'D':
case 'd':
strcat(bin, "1101");
break;
case 'E':
case 'e':
strcat(bin, "1110");
break;
case 'F':
case 'f':
strcat(bin, "1111");
break;
default:
printf("\nInvalid hexadecimal digit %c",
hexdec[i]);
}
}
return bin;
}
Also, in case it helps, here is the main function where I call this function
int main ()
{
int command = 10010100; //This is in hex
char* binaryString = convertBinary(command);
printf("The coverted binary is: %s\n", binaryString);
}
I expect the function to return a string of the binary numbers that have been converted from an 8 digit hex number. However, the program just quits and doesn't output anything. When debugged with GDB, it lays out a warning saying,
warning: Critical error detected c0000374
There are multiple problems in your code:
You do not check the for memory allocation failure.
Since you allocate 9 bytes for hexdec, snprintf(hexdec, SIZE, "%08X", hex); should be
snprintf(hexdec, 9, "%08X", hex);
The definition of SIZE is missing, as well as the #include lines. Post the complete source of the program exhibiting the offending behavior.
There is no need to loop until the end of the string hexdec: since you convert the hex value with %08X, just loop with:
for (i = 0; i < 8; ++i)
You should free(hexdec) before leaving the convertBinary function.
The code and comment do not agree in int command = 10010100; //This is in hex, which one is wrong? Probably both.
There is no need to use long type for i, int will suffice. Conversely, the argument hex should have unsigned int type.
Here is a simplified version of your code:
#include <stdio.h>
#include <stdlib.h>
char *convertBinary(unsigned int hex) {
char *bin = calloc(33, 1);
int i;
if (bin) {
for (i = 32; i-- > 0;) {
bin[i] = '0' + (hex & 1);
hex >>= 1;
}
}
return bin;
}
int main() {
int command = 0x10010100; //This is in hex
char *binaryString = convertBinary(command);
if (binaryString == NULL) {
printf("Memory allocation failure\n");
} else {
printf("The converted binary is: %s\n", binaryString);
free(binaryString);
}
return 0;
}
I'm doing an exercise from KNKings book "C Programming: A modern approach" which involves converting a phone number in alphabetic form, entered by the user, into numeric form. When the program encounters non-alphabetic characters (digits or punctuations, for example), it should leave them unchanged. I may assume that the user only enters upper-case letters.
However, my program seems to produce garbage, to say the least.
#include <stdio.h>
#define MAX_SIZE 50
int main(void)
{
char alphabetic[MAX_SIZE], ch;
int num_elements = 0;
printf("Enter phone number: ");
int i;
for (i = 0; i < MAX_SIZE && ((ch = getchar()) != '\n'); i++){
alphabetic[i] = ch;
num_elements++;
}
for (i = 0; i <= num_elements; i++){
switch (alphabetic[i]){
case 'A': case 'B': case 'C': alphabetic[i] = '2'; break;
case 'D': case 'E': case 'F': alphabetic[i] = '3'; break;
case 'G': case 'H': case 'I': alphabetic[i] = '4'; break;
case 'J': case 'K': case 'L': alphabetic[i] = '5'; break;
case 'M': case 'N': case 'O': alphabetic[i] = '6'; break;
case 'P': case 'R': case 'S': alphabetic[i] = '7'; break;
case 'T': case 'U': case 'V': alphabetic[i] = '8'; break;
case 'W': case 'X': case 'Y': alphabetic[i] = '9'; break;
default: break;
}
}
printf("%s\n", alphabetic);
return 0;
}
In particular, I enter: COLLECT-800.
It outputs something like this: u░#■ ║k ╩
What did I do wrong?
You have the right idea, but there are two things missing in your program:
Most importantly, the null terminator at the end of the string. After your for loop in which you read the number, add the line:
alphabetic[i] = '\0';
If the user enters lowercase letters, they are ignored in the switch statement. To get around this, include <ctype.h> and change the switch quantity from alphabetic[i] to toupper(alphabetic[i]). Calling toupper on an already upper case letter is benign.
You're not putting a null-terminator anywhere so it's undefined behavior when you read the string regardless of whether you modified it afterwards. Put this line:
alphabetic[num_elements] = 0;
After your for (i = 0; i < MAX_SIZE &&... loop.
Personally, I wouldn't do the getchar loop and instead read in the string like this:
scanf("%49s", alphabetic); // reads in a string up to 50 characters
for (i = 0; alphabetic[i]; i++) { ...
In the following program, I need to change the initial and final characters to their respective characters as mentioned below in case but this is giving me an infinite loop. What should I do to fix it?
int main(void)
{
char state ='t';
char word[20]="aaabbccaaaaccbbb";
int initiallength = strlen(word)-1; strcat(word,"a");
while(strlen(word)-1 >initiallength)
{
switch(state)
{
case 't':
switch(word[strlen(word)-1])
{
case 'a':
word[strlen(word)-1]='b'; break;
case 'b':
word[strlen(word)-1]='c'; break;
case 'c':
word[strlen(word)-1]='d'; break;
case 'd':
word[strlen(word)-1]='\0'; break;
}
switch(word[0])
{
case 'a':
word[0]='b'; break;
case 'b':
word[0]='c'; break;
case 'c':
word[0]='d'; break;
case 'd':
word[0]='\0'; break;
}
}
}
}
If I understand correctly what you want to do is swap the first and last characters in the given string. If that's the case first your code is way too complicated and second the reason you're getting an infinite loop is because the condition strlen(word)-1 >initiallength is always true.
Test if word is empty
int main(void){
char state ='t';
char word[20]="aaabbccaaaaccbbb";
int initiallength = strlen(word)-1;
strcat(word,"a");
while(strlen(word)-1 >initiallength && strlen(word) >= 0){
printf("%d %d\n", strlen(word)-1, initiallength);
printf("%d len %s\n", strlen(word), word);
switch(state){
case 't':
switch(word[strlen(word)-1]){
case 'a':
case 'b':
case 'c':
word[strlen(word)-1]++;
break;
case 'd':
word[strlen(word)-1] = '\0';
break;
}
switch(word[0]){
case 'a':
case 'b':
case 'c':
word[0]++;
break;
case 'd':
word[0] = '\0';
break;
}
}
}
}