How to read a binary number as input? - c++

Is there a way for the user to input a binary number in C or C++?
If we write something like
int a = 0b1010;
std::cout << a << std::endl
Then the output comes out to be 10 (when using the appropriate compiler extensions).
but when we try to write
int n;
std::cin >> n;
int t = 0bn;
It gives us an error so can anyone suggest that how can we directly read binary number as input rather than using string to store input?

There is a bit of confusion here, let's disentangle it a bit.
0b1010 is an integer literal, a constant, compile-time integer value written in base 2. Likewise, 0xA is a literal in base 16 and 10 is in base 10. All of these refer to the same integer, it is just a different way of telling the compiler which number you mean. At runtime, in memory, this integer is always represented as a base-2 number.
std::cout << a; takes the integer value of a and outputs a string representation of it. By default it outputs it in base 10, but you can i.e use the std::hex modifier to have it output it in base 16. There is no predefined modifier to print in binary. So you need to do that on your own (or google it, it is a common question).
0b at last, is only used to define integer literals. It is not a runtime operator. Recall, all ints are represented as base 2 numbers in memory. Other bases do not exist from a machine point of view, int is int, so there is nothing to convert. If you need to read a binary number from a string, you would roll the reverse code to what you do to print it (std::cin >> n assumes that the input is a base 10 number, so it reads a wrong number if the input is actually intended to be in base 2).

While there is no function to read binary numbers directly, there are functions, strtox (where x represents the data type) to convert a string containing a binary number (or a number of any other base) to a numeric value.
So the solution is to first read the number as a string and then convert it.
Example:
char input[100];
char *endpointer;
<read input using either C or C++ syntax>
int n = (int) strtol(input, &endpointer, 2);

To take a binary number as input, there are two ways I use frequently:
(Keynote: Take the input as string!!! use: #include <string>)
The to_ulong() method of the bitset template of the bitset library
for this you need to include the bitset library using #include <bitset>
Example:
string s;
cin>>s; // Suppose s = "100100101"
int n = (int) bitset<64>(s).to_ulong();
cout<<n; // 293
Explore more about bitset here and about to_ulong() here.
The stoi() method of the string library
for this you need to include the string library using #include <string>
Example:
string s;
cin>>s; // Suppose s = "100100101"
int n = stoi(s, 0, 2);
cout<<n; // 293
Explore the format of stoi() here.

rather do it yourself:
uint32_t a = 0;
char c;
while ((c = getchar()) != '\n') { // read a line char by char
a <<= 1; // shift the uint32 a bit left
a += (c - '0') & 1; // convert the char to 0/1 and put it at the end of the binary
}
printf("%u\n", a);

Related

How to convert a "char number" into an int WITHOUT use of magic numbers? (in C++)

In other words, based on the ASCII table, from the range of '0' to '9',
how may I convert them into integers 0 to 9?
A solution such as:
char a = '6';
int b = a-48;
has already been floating around these parts, but I was wondering if there are other ways to go about this without the use of magic numbers?
Since '0' is not guaranteed to be 48, but the numbers are guaranteed to be consecutive, you can use a-'0'.
If you really want to, you could use a stringstream like this:
#include <string>
#include <sstream>
int charToInt(char c) {
// initialize a buffered stream with a 1-character string
std::stringstream ss(std::string(1,c));
// read an int from the stream
int v;
ss >> v;
return v;
}
Not the simplest way to do the conversion, but this way you don't see any of the implementation details involving "magic" number or character. You also get error handling (an exception is thrown) if the caracter was not a number.
On the other hand, if you're absolutely certain that the character c is in the '0'..'9' range, I don't see why not use c - '0'.
Another solution is to replace c - 48 with c & 0xf, but that still involves magic numbers and is less readable than c - '0'
The ascii table is ordered in an hexadecimal way, so it's very easy to change numbers characters to real number value, or another things like to Uppercase to Lower...
As the numbers begin in the 0x30, then 0x30 =0 , 0x31 = 1, 0x32 =2, etc, you must just remove the 0x30 to get the real value.
char number='2';
int numberValue = (int)number - 0x30; /* you can rest the '0' value too */
As it, to convert an int to char is the same, just add it the 0x30.
int numberValue=5;
char number = (int)numberValue +0x30; /* or add '0' to your var */
Subtract ASCII zero from the number:
char a = '2';
int b = a-'0';
If you can't use '0', how about that kind of cheating?
(int)(a + 2) % 10;
If it's a char, not a char pointer, you can do this:
int convert (char x)
{
return (int(x) - int('0'));
}

c++ convert character to integer using ASCII

I am working on a little c++ project that receives a char array input from the user. Depending on the value, I am converting it to an int. I understand there are better ways of doing this but I thought I'd try to convert it through ASCII to allow other uses later on. My current code for the conversion is:-
int ctoi(char *item){
int ascii, num = 0;
ascii = static_cast<int>(item[0]);
if(ascii >= 49 && ascii <=57){
num = ascii - 48;
}else{
return 0;
}
ascii = static_cast<int>(item[1]);
if(ascii >= 48 && ascii <=57){
num = num * 10;
num = num + (ascii - 48);
}else{
return 0;
}
return num;
}
It receives a input into the char array item[2] in the main function and passes this to the conversion function above. The function converts the first char to ASCII then the decimal value of the ASCII to num if its between 1 and 9, then it converts the second char to ASCII, if it is between 0 and 9, it times the value in num by 10 (move along one unit) and adds the decimal value of the ASCII value. At any point it may fail, it returns the value 0 instead.
When I cout the function after receiving a value and run this code in a console, it works fine for single digit numbers (1 - 9), however when I try to use a double digit number, it repeats digits such as for 23, it will output 2233.
Thanks for any help.
I wonder how you're reading the input into a two-character array. Note that it's customary to terminate such strings with a null character, which leaves just one for the actual input. In order to read a string in C++, use this code:
std::string s;
std::cin >> s;
Alternatively, for a whole line, use this:
std::string line;
getline(std::cin, line);
In any case, these are basics explained in any C++ text. Go and read one, it's inevitable!

convert char[] of hexadecimal numbers to char[] of letters corresponding to the hexadecimal numbers in ascii table and reversing it

I have a char a[] of hexadecimal characters like this:
"315c4eeaa8b5f8aaf9174145bf43e1784b8fa00dc71d885a804e5ee9fa40b16349c146fb778cdf2d3aff021dfff5b403b510d0d0455468aeb98622b137dae857553ccd8883a7bc37520e06e515d22c954eba5025b8cc57ee59418ce7dc6bc41556bdb36bbca3e8774301fbcaa3b83b220809560987815f65286764703de0f3d524400a19b159610b11ef3e"
I want to convert it to letters corresponding to each hexadecimal number like this:
68656c6c6f = hello
and store it in char b[] and then do the reverse
I don't want a block of code please, I want explanation and what libraries was used and how to use it.
Thanks
Assuming you are talking about ASCII codes. Well, first step is to find the size of b. Assuming you have all characters by 2 hexadecimal digits (for example, a tab would be 09), then size of b is simply strlen(a) / 2 + 1.
That done, you need to go through letters of a, 2 by 2, convert them to their integer value and store it as a string. Written as a formula you have:
b[i] = (to_digit(a[2*i]) << 4) + to_digit(a[2*i+1]))
where to_digit(x) converts '0'-'9' to 0-9 and 'a'-'z' or 'A'-'Z' to 10-15.
Note that if characters below 0x10 are shown with only one character (the only one I can think of is tab, then instead of using 2*i as index to a, you should keep a next_index in your loop which is either added by 2, if a[next_index] < '8' or added by 1 otherwise. In the later case, b[i] = to_digit(a[next_index]).
The reverse of this operation is very similar. Each character b[i] is written as:
a[2*i] = to_char(b[i] >> 4)
a[2*i+1] = to_char(b[i] & 0xf)
where to_char is the opposite of to_digit.
Converting the hexadecimal string to a character string can be done by using std::substr to get the next two characters of the hex string, then using std::stoi to convert the substring to an integer. This can be casted to a character that is added to a std::string. The std::stoi function is C++11 only, and if you don't have it you can use e.g. std::strtol.
To do the opposite you loop over each character in the input string, cast it to an integer and put it in an std::ostringstream preceded by manipulators to have it presented as a two-digit, zero-prefixed hexadecimal number. Append to the output string.
Use std::string::c_str to get an old-style C char pointer if needed.
No external library, only using the C++ standard library.
Forward:
Read two hex chars from input.
Convert to int (0..255). (hint: sscanf is one way)
Append int to output char array
Repeat 1-3 until out of chars.
Null terminate the array
Reverse:
Read single char from array
Convert to 2 hexidecimal chars (hint: sprintf is one way).
Concat buffer from (2) to final output string buffer.
Repeat 1-3 until out of chars.
Almost forgot to mention. stdio.h and the regular C-runtime required only-assuming you're using sscanf and sprintf. You could alternatively create a a pair of conversion tables that would radically speed up the conversions.
Here's a simple piece of code to do the trick:
unsigned int hex_digit_value(char c)
{
if ('0' <= c && c <= '9') { return c - '0'; }
if ('a' <= c && c <= 'f') { return c + 10 - 'a'; }
if ('A' <= c && c <= 'F') { return c + 10 - 'A'; }
return -1;
}
std::string dehexify(std::string const & s)
{
std::string result(s.size() / 2);
for (std::size_t i = 0; i != s.size(); ++i)
{
result[i] = hex_digit_value(s[2 * i]) * 16
+ hex_digit_value(s[2 * i + 1]);
}
return result;
}
Usage:
char const a[] = "12AB";
std::string s = dehexify(a);
Notes:
A proper implementation would add checks that the input string length is even and that each digit is in fact a valid hex numeral.
Dehexifying has nothing to do with ASCII. It just turns any hexified sequence of nibbles into a sequence of bytes. I just use std::string as a convenient "container of bytes", which is exactly what it is.
There are dozens of answers on SO showing you how to go the other way; just search for "hexify".
Each hexadecimal digit corresponds to 4 bits, because 4 bits has 16 possible bit patterns (and there are 16 possible hex digits, each standing for a unique 4-bit pattern).
So, two hexadecimal digits correspond to 8 bits.
And on most computers nowadays (some Texas Instruments digital signal processors are an exception) a C++ char is 8 bits.
This means that each C++ char is represented by 2 hex digits.
So, simply read two hex digits at a time, convert to int using e.g. an istringstream, convert that to char, and append each char value to a std::string.
The other direction is just opposite, but with a twist.
Because char is signed on most systems, you need to convert to unsigned char before converting that value again to hex digits.
Conversion to and from hexadecimal can be done using hex, like e.g.
cout << hex << x;
cin >> hex >> x;
for a suitable definition of x, e.g. int x
This should work for string streams as well.

converting string to int

hello i have a problem i am trying to convert a string like "12314234" to int
so i will get the first number in the string.
from the example of string that is shown above i want to get '1' in int.
i tried :
string line = "12314234";
int command = line.at(0);
but it puts inside command the ascii value of 1 and not the number 1.
thanks in advance.
int command = line.at(0) - '0';
The numerical values of digit characters are required to be next to each other. So this works everywhere and always. No matter what character-set your compiler uses.
To convert a numerical character ('0' – '9') to its corresponding value, just substract the ASCII code of '0' from the result.
int command = line.at(0) - '0';
The standard function to convert an ascii to a integral value is strtol (string to long) from stdlib (#include <cstdlib>). For information, see http://en.wikipedia.org/wiki/Strtol and then the link off that page entitled Using strtol correctly and portably. With strtol you can convert one numeric character, or a sequence of numeric characters, and they can be multiple bases (dec, hex, etc).
i am trying to convert a string like "12314234" to int
Boost has a library for this:
int i = boost::lexical_cast<int>(str);
Sorry to join this party late but what is wrong with:
int value;
std::string number = "12345";
std::istringstream iss(number);
iss >> value;
If you are passing hexadecimal around (and who isn't these days) then you can do:
int value;
std::string number = "0xff";
std::istringstream iss(number);
iss >> std::hex >> value;
It's C++ and has none of this hackish subtraction of ASCii stuff.
The boost::lexical_cast<>() way is nice and clean if you are using boost. If you can't guarantee the string being passed will be a number then you should catch the thrown error.

I need to randomize a number between two hex numbers, represented as strings

...and return the number as string.
How can I do that? Is there any library for that?
You can use std::istringstring from <sstream> to convert the strings to integers. Then you can use rand or random to get a random number, which you can constrain to the interval using modular arithmetic, and then you can convert the number to a hexadecimal string using std::ostringstream.
#include <sstream>
#include <string>
#include <cstdlib>
int hexstr2int(const std::string& str)
{
int result;
std::istringstream iss(str);
iss >> result;
return result;
}
std::string int2hexstr(int number)
{
std::ostringstream oss;
oss << std::hex << number;
return number.str();
}
int randint(int lower, int upper)
{
int range = upper - lower;
return ((rand()%range)+lower);
}
std::string randhexstr(const std::string& a, const std::string& b)
{
int lower = hexstr2int(a);
int upper = hexstr2int(b);
return int2hexstr(randint(lower,upper));
}
boost::lexical_cast is pretty useful and convenient for converting between strings and numbers. It lets you write expressions like:
int some_number = boost::lexical_cast<int>(some_string);
or the other way:
std::string some_string = boost::lexical_cast<std::string>(some_int);
My reply isn't going to be as useful as others, but this is really a basic programming problem.
Learning to program consists in some way in learning how to break problems into subproblems, up to a point where the small problem is manageable.
You want to randomize a number between two hex numbers, represented as strings.
The starting point here is that you want a random number. Finding out how to get a random number shouldn't be that complicated.
Now perhaps the random number function you have doesn't accept a range.
Say for example it produces floating numbers between 0 and 1, you want numbers between a and b. It's not hard to find you can convert a number n from 0 - 1 to a number m from a - b : m = n*(b-a)+a
Sometimes you'll have a random function that gives an integer number between 0 and the given argument; sometimes it'll be different -- apply the same reasoning.
Then you need to find the a and b values for your range, but you have strings representing hex numbers. Well you'll obviously will have to find a way to convert them to decimal numbers. It shouldn't be hard to find a function that does that for you. If you don't, parsing a hex string isn't that hard.
And voilà. By breaking the problem into subproblems, you managed to find your way to the solution.