Number(string binary)
{
int raw_string_int[size];
char raw_string_char[size];
strcpy(raw_string_char,binary.c_str());
printf("Raw String is %s",raw_string_char);
for (int i=0;i<size;i++)
{
raw_string_int[i] = int(raw_string_char[i]);
printf("%i\n",int(raw_string_char[i]));
if (raw_string_int[i] != 0 || raw_string_int[i] != 1)
{
printf("ERROR NOT A BINARY NUMBER\n");
exit(0);
}
}
Hi, I'm entering 0001 as binary at the command prompt, but raw_string_char is being appended with two extra numbers. Can anyone explain to me why this is? Is the carriage return being brought in as a char?
Here is What I'm getting at the command prompt:
./test
0001
Raw String is 000148
ERROR NOT A BINARY NUMBER
You forgot the "\n" in your first printf. The 48 is from the second printf, and is the result of casting the first '0' (ASCII 0x30 = 48) to an int.
To convert a textual 0 or 1 to the corresponding integer, you need to subtract 0x30.
Your assumption that char('0') == int(0) and char('1') == int(1) just doesn't hold. In ASCII these characters have the values of 48 and 49.
What you should do to get integer values of digit characters is substract '0' instead of simple casting (raw_string_int[x] = raw_string_char[x] - '0';).
I think you have conceptual problems though. The array can't be full of valid values to the end (the corresponding C-string would at least contain a null-terminator, which is not a valid binary character). You can use the string's size() method to find out how many characters the string actually contains. And naturally you are risking buffer overflows, should the binary string contain size characters or more.
If the intention is to check if the input is a valid binary number, why can't you test the original string, why would you copy data around to two more arrays?
You're printing every character in raw_string_char. C-style strings go until the first zero character (that's '\0', not 0).
Change to for (int i = 0; raw_string_char[i] != 0 && i < size; i++).
Like others said, '0' is converted to an integer 48. You don't really need to convert the C++ string to a C style string. You can use iterators or the index operator [] on the C++ string. You also need to use logical AND && rather than logical OR || in your if statement.
#include<cstdio>
#include<string>
void Number(std::string binary) {
for(std::string::const_iterator i = binary.begin(); i != binary.end(); i++ )
if( *i != '0' && *i != '1')
{
printf("ERROR NOT A BINARY NUMBER\n");
return;
}
}
int main() {
Number("0001");
}
The raw_string_char is never initialized, the extra characters are possibly due to this. Use memset to initialize the array.
memset(raw_string_array, 0, size);
Related
I need to define an array of chars. One of the chars in the array must be 0.
I tried something like this:
array[i] = '0';
but when I send array to the output with:
cout << array << endl;
the 0 char is interpreted as a string separator, so only the part of array comprised between indices 0 and i-1 is printed.
How should I define the 0 character in such a way that array is printed as a whole sequence of chars, without interruptions? Could the problem depend on the nature of cout (I mean, maybe my assignment of 0 char is correct, but the printing function has some weird behavior I have ignored)?
Thanks for the help.
Character literal (or named as character constant in C) '0' is not the terminating zero of strings. It seems you used either '\0' or integer literal 0 instead of '0'. '\0' or 0 are indeed the terminating zero and has value 0 while '0' for example in ASCII has value 48.
Take into account that you wrote that you are programming in C but showed a C++ code snippet.:)
array[i] = '0'; // ASCII code of 0 as a character goes in
array[i] = 0; // string terminator character, can also be written as '\0', same thing
If you just want to send the ASCII character 0, you can write:
char a='0'
or
char a=48
The problem I still don't know how to solve is how to send the null byte to a serial port, because 0 or \0 are the same and always interrupt the string!
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!
I am trying to improve my understanding of C++, pointer arithmetic especially. I use atoi pretty often, but I have rarely given thought as to how it works. Looking up how it is done, I understand it mostly, but there is one thing that I am confused about.
Here is an example of a solution I have found online:
int atoi( char* pStr )
{
int iRetVal = 0;
if ( pStr )
{
while ( *pStr && *pStr <= '9' && *pStr >= '0' )
{
iRetVal = (iRetVal * 10) + (*pStr - '0');
pStr++;
}
}
return iRetVal;
}
I think the main reason I have had a hard time grasping how atoi as been done in the past is the way characters are compared. The "while" statement is saying while the character exists, and the character is less-than-or-equal-to 9, and it is greater-than-or-equal-to 0 then do stuff. This statement says two things to me:
Characters can be compared to other characters logically (but what is the returned value?).
Before I looked into this I suppose I knew it subconsciously but I never actually thought about it, but a '5' character is "smaller" than a '6' character in the same way that 5 is less than 6, so you can compare the characters as integers, essentially (for this intent).
Somehow while (*sPtr) and *SPtr != 0 are different. This seems obvious to me, but I find that I cannot put it into words, which means I know this is true but I do not understand why.
Edit: I have no idea what the *pStr - '0' part would do.
Any help making sense of these observations would be very... helpful! Thanks!
while the character exists
No, not really. It says "while character is not 0 (or '\0'). Basically, ASCII character '\0' indicates an end of a "C" string. Since you don't want to go past the end of a character array (and the exact length is not known), every character is tested for '\0'.
Characters can be compared to other characters logically
That's right. Character is nothing but a number, well, at least in ASCII encoding. In ASCII, for instance, '0' corresponds to a decimal value of 48, '1' is 49, 'Z' is 90 (you can take a look at ASCII Table here). So yeah, you can compare characters just like you compare integers.
Somehow while (*sPtr) and *sPtr != 0 are different.
Not different at all. A decimal 0 is a special ASCII symbol (nul) that is used to indicate the end of "C" string, as I mentioned in the beginning. You cannot see or print (nul), but it's there.
The *pStr - '0' converts the character to its numeric value '1' - '0' = 1
The while loop checks if we are not at the end of the string and that we have a valid digit.
A character in C is represented simply as an ASCII value. Since all the digits are consecutive in ASCII (i.e. 0x30 == '0' and 0x39 == '9' with all the other digits in between), you can determine if a character is a digit by simply doing a range check, and you can get the digit's value by subtracting '0'.
Note that posted implementation of atoi is not complete. Real atoi can process negative values.
Somehow while (*sPtr) and *sPtr != 0 are different.
These two expressions are the same. When used as condition, *sPtr is considered true when value stored at address sPtr is not zero, and *sPtr != 0 is true when value stored at address sPtr is not zero. Difference is when used somewhere else, then second expression evaluates to true or false, but the first one evaluates to stored value.
C-style strings are null-terminated.
Therefore:
while ( *pStr && *pStr <= '9' && *pStr >= '0' )
This tests:
*pStr that we have not yet reached the end of the string and is equivalent to writing *pStr != 0 (note without the single quote, ASCII value 0, or NUL).
*pStr >= '0' && *pStr <= '9' (perhaps more logically) that the character at *pStr is in the range '0' (ASCII value 48) to '9' (ASCII value 57), that is a digit.
The representation of '0' in memory os 0x30 and the representation of '9' is 0x39. This is what the computer sees, and when it compares them with logical operators, it uses these values. The nul-termination character is represented as 0x00, (aka zero). The key here is that chars are just like any other int to the machine.
Therefore, the while statement is saying:
While the char we are examining is valid (aka NOT zero and therefore NOT a nul-terminator), and its value (as the machine sees it) is less than 0x39 and its value is greater than 0x30, proceed.
The body of the while loop then calculates the appropriate value to add to the accumulator based on the integer's position in the string. It then increments the pointer and goes again. Once it's done, it returns the accumulated value.
This chunk of code is using ascii values to accumulate an integer tally of it's alpha equivalent.
In regards to your first numbered bullet, it seems quite trivial that when comparing anything the result is boolean. Although I feel like you were trying to ask if the compiler actually understands "characters". To my understanding though this comparison is done using the ascii values of the characters. i.e. a < b is interpreted as ( 97 < 98).
(Note that it is also easy to see that ascii values are used when you compare 'a' and 'A', as 'A' is less than 'a')
Concerning your second bullet, it seems that the while loop is checking that there is in fact an assigned value that is not NULL (ascii value of 0). The and operator produces FALSE as soon as a false statement is encountered, so that you don't do comparison on a NULL char. As for the rest of the while loop, it is doing ascii comparison as I mentioned about bullet 1. It is just checking whether or not the given character corresponds to an ascii value that is related to a number. i.e. between '0' and '9' (or ascii: between 48 and 57)
LASTLY
the (*ptr-'0') is the most interesting part in my opinion. This statement returns an integer between 0 and 9 inclusive. If you take a look at an ascii chart you will notice the numbers 0 through 9 are beside each other. So imagine '3'-'0' which is 51 - 48 and produces 3! :D So in simpler terms, it is doing ascii subtraction and returning the corresponding integer value. :D
Cheers, and I hope this explains a bit
Let's break it down:
if ( pStr )
If you pass atoi a null pointer, pStr will be 0x00 - and this will be false. Otherwise, we have something to parse.
while ( *pStr && *pStr <= '9' && *pStr >= '0' )
Ok, there's a bunch of things going on here. *pStr means we check if the value pStr is pointing to is 0x00 or not. If you look at an ASCII table, the ASCII for 0x00 is 'null' and in C/C++ the convention is that strings are null terminated (as opposed to Pascal and Java style strings, which tell you their length then have that many characters). So, when *pStr evaluates to false, our string has come to an end and we should stop.
*pStr <= '9' && *pStr >= '0' works because the values for the ASCII characters '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' are all contiguous - '0' is 0x30 and '9' is 0x39, for example. So, if pStr's pointed to value is outside this range, then we're not parsing an integer and we should stop.
iRetVal = (iRetVal * 10) + (*pStr - '0');
Because of the properties of ASCII numerals being contiguous in memory, it so happens that if we know we have a numeral, *pStr - '0' evaluates to its numerical value - 0 for '0' (0x30 - 0x30), 1 for '1' (0x31 - 0x30)... 9 for '9'. So we shift our number up and slide in the new place.
pStr++;
By adding one to the pointer, the pointer points to the next address in memory - the next character in the string we are converting to an integer.
Note that this function will screw up if the string is not null terminated, it has any non numerals (such as '-') or if it is non-ASCII in any way. It's not magic, it just relies on these things being true.
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.
Keep in mind, if you choose to answer the question, I am a beginner in the field of programming and may need a bit more explanation than others as to how the solutions work.
Thank you for your help.
My problem is that I am trying to do computations with parts of a string (consisting only of numbers), but I do not know how to convert an individual char to an int. The string is named "message".
for (int place = 0; place < message.size(); place++)
{
if (secondPlace == 0)
{
cout << (message[place]) * 100 << endl;
}
}
Thank you.
If you mean that you want to convert the character '0' to the integer 0, and '1' to 1, et cetera, than the simplest way to do this is probably the following:
int number = message[place] - '0';
Since the characters for digits are encoded in ascii in ascending numerical order, you can subtract the ascii value of '0' from the ascii value of the character in question and get a number equal to the digit.