I am trying to read in multiple lines in a file ,convert each line to binary. I reckon that for each line, we need to shift every 4 char in order to store the next 4. However I am not sure if the only way to store binary i.e. 0010 is as a String.Can someone please help? I can't get my head around how to do this. Many thanks!
Asked
Active
Viewed 376 times
0
-
Hexadecimal, decimal and binary are only representations of integer numbers and they can be stored as a string. Your `strcat` idea works, but you must zero-terminate `inter` and you should use ASCII codes for the digits, i.e. `'0'` and `'1'` in single quotes instead of `0` and `1`. Better yet, use string literals in double quotes: `strcat(output, "0011")`. – M Oehm Oct 08 '14 at 11:15
-
2Forget your for loop. This is definitly awkward (you need 16 case labels). For each line read use `strtol` to convert the hex string into a number, and then convert that number into binary for example by using the shift (<<) operator. – Jabberwocky Oct 08 '14 at 11:17
-
@MOehm Thanks! By zero-terminate, do you mean adding inter [4] ='/0'? I wish I could store 0011 as something else rather than assigning an array each time.. – stillAFanOfTheSimpsons Oct 08 '14 at 11:19
-
@MichaelWalz Thank you! This sounds much more feasible. Could you elaborate? Can I not convert hex string directly to base 2 number using strtol? Or you mean convert the one char of the hex string to binary at a time, and then shift the numbers? – stillAFanOfTheSimpsons Oct 08 '14 at 11:26
-
@MichaelWalz : Don't you mean `>>` (and bitwise `&`)? And then of course we need to convert the bits back to char, which we can do with '|' or addition. – PM 2Ring Oct 08 '14 at 11:28
-
You need to use strtol to get the number and then use http://stackoverflow.com/questions/111928/is-there-a-printf-converter-to-print-in-binary-format to get the binary equivalent. As M Oehm said, these are all just representation of a number. – vvvv Oct 08 '14 at 11:32
-
1user4056620 `strtol()` converts a string to a C long integer. And that integer is stored in memory as a binary number. But to get at those bits you need to use C's bit manipulation operators like `>>`, `&` and `|'. – PM 2Ring Oct 08 '14 at 11:32
-
In python its just `print(bin(int(line,16))[2:])` where `line` contains hex string – Ashwani Oct 08 '14 at 11:35
-
2@AshwaniDausodia : maybe, but we are talking C here. – Jabberwocky Oct 08 '14 at 11:36
-
Eg. `n = strtol("1e2", NULL, 16);` converts the hex string to a C integer. `n&1` gives you the value of the least significant bit (LSB) as a C integer, which in this case is 0. `(n>>1)&1` shifts all the bits of `n` one place to the right and then gives you the LSB of that, which is 1. Make sense? – PM 2Ring Oct 08 '14 at 11:37
-
@PM2Ring : no I meant `<<` and yes we'd also need `&`. – Jabberwocky Oct 08 '14 at 11:38
-
1@MichaelWalz : Ok. I guess that makes sense since were dealing with bitstrings of a fixed known length. And my way unfortunately generates the bits in reverse order. – PM 2Ring Oct 08 '14 at 11:41
4 Answers
1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n, k;
char * nptr = "1e2", *endptr; // nptr contains hex
n = strtol(nptr, &endptr, 16); // n contains decimal
char bin[33]; // bin contains binary
int index = 0;
while(n != 0)
{
if (n & 1)
bin[index++] = '1';
else
bin[index++] = '0';
n = n >> 1;
}
bin[index] ='\0';
printf("%s", strrev(bin));
return 0;
}
edit:
if you want a 32 bit number with leading zeros then:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int n, c, k;
char * nptr = "1e2", *endptr; // nptr contains hex
n = strtol(nptr, &endptr, 16);
char bin[33];
int index = 0;
for (c = 31; c >= 0; c--)
{
k = n >> c;
if (k & 1)
bin[index++] = '1';
else
bin[index++] = '0';
}
bin[index] = '\0';
printf("%s", bin);
return 0;
}

Ashwani
- 1,938
- 11
- 15
-
Thanks! but I don't quite get the logic here: does n = strtol(nptr, &endptr, 16) convert nptr to decimal number? should it be strtol(nptr, &endptr, 10)? Another thing is that science n is decimal, i.e. 234, how can we use n & 1 to get the binary bit in bin? – stillAFanOfTheSimpsons Oct 08 '14 at 12:12
-
suppose `n = 234` or `11101010` in binary. `n & 1` is nothing but `11101010 & 00000001` which will be `1` if rightmost bit of `n` is `1`, `0` otherwise. If you don't know about **bitwise** operators, google it. – Ashwani Oct 08 '14 at 12:18
-
@PM 2Ring you can easily modify it to get 12 bit output. Assuming 12 bits are enough to hold the value, you can igonre first 20 charcters in string `bin`. – Ashwani Oct 08 '14 at 12:19
-
Sure. And I guess it's a good exercise for the OP to do that modification, once they understand your code better. It seems they don't quite get how all `int`s are actually stored as binary. But I let you try to explain that. :) – PM 2Ring Oct 08 '14 at 12:28
-
@user4056620 This link may help you [Number Bases and C’s Bitwise Operators](http://www.ece.ubc.ca/~edc/380.jan98/lectures/lec3.pdf) – Ashwani Oct 08 '14 at 13:14
1
This accepts a three character hex input and outputs a 12 character binary string. The function will accept arguments to change the input and output lengths. iLenOut should be at least the length of the hex input * 4.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
int hextobin ( char *pacHexIn, char *pacBinOut, int iLenOut) {
char acHexChars[17] = { "0123456789abcdef"};
char *pcEachHex = NULL;
unsigned int uiHexIndex = 0;
int iEachBit = 0;
int iInputLen = 0;
int iOutputLen = iLenOut;
if ( iLenOut % 4) {
printf ( "as each hex character will result in 4 bits, use an even multiple of 4\n");
return 2;
}
while ( iOutputLen) {
pacBinOut[iOutputLen] = '0';
iOutputLen--;
}
iOutputLen = iLenOut;
iInputLen = strlen ( pacHexIn); // get length of input
while ( iInputLen > 0) {
iInputLen--;
iOutputLen -= 4;
pacHexIn[iInputLen] = tolower( pacHexIn[iInputLen]); // make sure input is lower case
if ( ( pcEachHex = strchr ( acHexChars, pacHexIn[iInputLen])) != NULL) { // get index to acHexChars
uiHexIndex = pcEachHex - acHexChars; // difference will be the value of the hex char f=15...
for ( iEachBit = 3; iEachBit >= 0; iEachBit--) { // loop through the bits
if ( 1 & ( uiHexIndex >> iEachBit)) { // right shift and compare to 1
pacBinOut[ iOutputLen + ( 3 - iEachBit)] = '1'; // set to 1
}
else {
pacBinOut[ iOutputLen + ( 3 - iEachBit)] = '0'; // set to 0
}
}
}
else {
printf ( "Only input hex values 0-9 and a-f\n"); // invalid input
return 1;
}
}
pacBinOut[iLenOut] = '\0'; // make sure string is terminated
return 0;
}
int main()
{
char acInput[9] = { 0};
char acBinary[33] = { "00000000000000000000000000000000"};
scanf ( "%3s", acInput); // input 3 hex characters, acInput will allow for up to 8 characters
if ( ( hextobin ( acInput, acBinary, 12)) == 0) { // return binary string of 12 characters, acBinary will allow up to 32
printf ( "%s\n", acBinary); // print result
}
else {
printf ( "conversion failed\n");
}
return 0;
}

user3121023
- 8,181
- 5
- 18
- 16
-
can you elaborate what uiHexIndex = pcEachHex - acHexChars does? – stillAFanOfTheSimpsons Oct 10 '14 at 10:37
-
Got it! Thanks! Is it the same as using strtol() to convert a to decimal, and then `for ( iEachBit = 3; iEachBit >= 0; iEachBit--)` to loop through the number? – stillAFanOfTheSimpsons Oct 10 '14 at 11:38
0
Try this:
char inter[5];
const char *binary = std::bitset<4>(input [i] -'0').to_string().c_str(); //to binary
strcpy(inter, binary);
need to include <bitset>, <string> and <string.h>

Dr. Debasish Jana
- 6,980
- 4
- 30
- 69
-
2Neither this method nor the includes are [tag:c], which is what the OP asks for. While it may be interesting to the OP to see how it's done in *another language*, it is not an answer to the question. – Jongware Oct 08 '14 at 12:59
0
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char *argv[]){
static const char *table[] = {
"0000","0001","0010", "0011",
"0100","0101","0110", "0111",
"1000","1001","1010", "1011",
"1100","1101","1110", "1111"
};
FILE *file = fopen("data.txt", "r");
char input[5], output[13] = {0};
while (fgets(input, 5, file)!=NULL){
char *p = output;
for ( int i = 0; i < 3; ++i){
if(isdigit(input[i]))
memcpy(p, table[input[i]-'0'], 4);
else //a-f
memcpy(p, table[tolower(input[i])-'a'+10], 4);
p += 4;
}
puts(output);
}
fclose(file);
return 0;
}

BLUEPIXY
- 39,699
- 7
- 33
- 70