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!
Related
For example, I have a string st="1234567" and I want to add st[0] and st[1] to char ch so that ch = 12, and then to convert that to an int x so that x = 12.
Is there a way to do this?
You can achieve it like this:
int x = 10*(st[0]-'0') + (st[1]-'0');
This works because subtracting '0' from a char representing a number results in that actual number. So for instance '5' - '0' == 5.
char ch so that ch = 12
That's not possible though. You can do char ch = 12, but that's not going to represent a 12, that will most likely just result in something that might not be printable. In ASCII that would be a "form feed" and if you tried to print that, it could perhaps put a newline (or skip to the next page if your editor supports that). If you want a string to hold "12", you can do it this way:
std::string twelve = st.substr(0, 2);
And from there a general way of converting to int would be
int x = std::stoi(twelve);
I am asking about the job of minus and plus notation on string , in this situation specifically :
Solver(string s) {
for (unsigned int i = 0; i < s.length(); i++) {
grid[i] = (int) (s[i] - '0'); // the minus here will remove 0's of string or not ?
}
}
int main() {
Solver ss(
(string) "850002400" + // the plus here will combine all strings together like Java or not ?
(string) "720000009" +
(string) "004000000" +
(string) "000107002" +
(string) "305000900" +
(string) "040000000" +
(string) "000080070" +
(string) "017000000" +
(string) "000036040"
);
}
operator+ for string concatenates them – as you discovered already. But there's no operator- for strings!
Have a close look, you are not subtracting from the string (s - '0'), but from the character s[i]. This won't remove the character from the string, but instead calculate a new value based on the character's value minus the value of zero character (which has a value of 48, in ASCII and compatible, at least – not the value null!). As digits are guaranteed to be contiguous by C++ standard (just like in C as well), you can reliably calculate decimal digits from characters that way.
This works for bases smaller than 10, too, but not larger ones, as next characters used for representation don't follow the decimal digits directly (and you might have to distinguish upper and lower case letters).
Side note: You don't need the cast to int: as type char is smaller in size than int, both operands will be promoted to int implicitly, so actually the calculation is done in int anyway and the result remains int...
string - C++ Reference
http://www.cplusplus.com/reference/string/string/
As is said in link above, the operator+ means "Concatenate strings".
If you want to CLIP the string, you can use the s.substr() function.
grid[i] = (int) (s[i] - '0')
the the minus in code means transform the 'char' to 'int'. For example,
string s="425";
char c = s[0]; //c='4';
int value = c-'0'; //value=4 it is a number
It is not the function of string, just a utilization of ASCII.
The function stoi(s[i]) can realize the same thing.
Subtracting '0' from any character of digit will return the integer value of that digit.
char seven = '7';
int value = (int)(seven - '0');
cout<<value<<endl;
Output:
7
In your example - was used to convert a character grid(1D) to integer grid(1D).
On the other hand, + sign between two or more string type data represent concatenation of string.
string s = "abc" + "def";
cout<<s<<endl;
Output:
abcdef
I am new to C so I do not understand what is happening in this line:
out[counter++] = recurring_count + '0';
What does +'0' mean?
Additionally, can you please help me by writing comments for most of the code? I don't understand it well, so I hope you can help me. Thank you.
#include "stdafx.h"
#include "stdafx.h"
#include<iostream>
void encode(char mass[], char* out, int size)
{
int counter = 0;
int recurring_count = 0;
for (int i = 0; i < size - 1; i++)
{
if (mass[i] != mass[i + 1])
{
recurring_count++;
out[counter++] = mass[i];
out[counter++] = recurring_count + '0';
recurring_count = 0;
}
else
{
recurring_count++;
}
}
}
int main()
{
char data[] = "yyyyyyttttt";
int size = sizeof(data) / sizeof(data[0]);
char * out = new char[size + 1]();
encode(data, out, size);
std::cout << out;
delete[] out;
std::cin.get();
return 0;
}
It adds the character encoding value of '0' to the value in recurring_count. If we assume ASCII encoded characters, that means adding 48.
This is common practice for making a "readable" digit from a integer value in the range 0..9 - in other words, convert a single digit number to an actual digit representation in a character form. And as long as all digits are "in sequence" (only digits between 0 and 9), it works for any encoding, not just ASCII - so a computer using EBCDIC encoding would still have the same effect.
recurring_count + '0' is a simple way of converting the int recurring_count value into an ascii character.
As you can see over on wikipedia the ascii character code of 0 is 48. Adding the value to that takes you to the corresponding character code for that value.
You see, computers may not really know about letters, digits, symbols; like the letter a, or the digit 1, or the symbol ?. All they know is zeroes and ones. True or not. To exist or not.
Here's one bit: 1
Here's another one: 0
These two are only things that a bit can be, existence or absence.
Yet computers can know about, say, 5. How? Well, 5 is 5 only in base 10; in base 4, it would be a 11, and in base 2, it would be 101. You don't have to know about the base 4, but let's examine the base 2 one, to make sure you know about that:
How would you represent 0 if you had only 0s and 1s? 0, right? You probably would also represent the 1 as 1. Then for 2? Well, you'd write 2 if you could, but you can't... So you write 10 instead.
This is exactly analogous to what you do while advancing from 9 to 10 in base 10. You cannot write 10 inside a single digit, so you rather reset the last digit to zero, and increase the next digit by one. Same thing while advancing from 19 to 20, you attempt to increase 9 by one, but you can't, because there is no single digit representation of 10 in base 10, so you rather reset that digit, and increase the next digit.
This is how you represent numbers with just 0s and 1s.
Now that you have numbers, how would you represent letters and symbols and character-digits, like the 4 and 3 inside the silly string L4M3 for example? You could map them; map them so, for example, that the number 1 would from then on represent the character A, and then 2 would represent B.
Of course, it would be a little problematic; because when you do that the number 1 would represent both the number 1 and the character A. This is exactly the reason why if you write...
printf( "%d %c", 65, 65 );
You will have the output "65 A", provided that the environment you're on is using ASCII encoding, because in ASCII 65 has been mapped to represent A when interpreted as a character. A full list can be found over there.
In short
'A' with single quotes around delivers the message that, "Hey, this A over here is to receive whatever the representative integer value of A is", and in most environments it will just be 65. Same for '0', which evaluates to 48 with ASCII encoding.
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.
the operator int() function converts the string to an int
class mystring
{
private:
chat str[20];
public:
operator int() // i'm assuming this converts a string to an int
{
int i=0,l,ss=0,k=1;
l = strlen(str)-1;
while(l>=0)
{
ss=ss+(str[l]-48)*k;
l--;
k*=10;
}
return(ss);
}
}
int main()
{
mystring s2("123");
int i=int(s2);
cout << endl << "i= "<<i;
}
So what's the logic behind operator int() ? What's the 48 in there? Can someone explain to me the algorithm behind the conversion from string to int.
Yes this converts a string to an integer. 48 is the ASCII value for '0'. If you subtract 48 from an ASCII digit you'll get the value of the digit (ex: '0' - 48 = 0, '1' - 48 = 1, ..). For each digit, your code calculates the correct power of 10 by using k (ranges between 1...10^{ log of the number represented by the input string}).
It does indeed convert a string to an integer. The routine assumes that all characters are decimal digits (things like minus sign, space, or comma will mess it up).
It starts with the ones place and moves through the string. For each digit, it subtracts off the ASCII value of '0', and multiplies by the current place value.
This does indeed convert the string to an integer. If you look at an ascii table the numbers start at the value 48. Using this logic (and lets say the string "123") the while loop will do:
l=2
ss=0+(51-48)*1
so in this case ss = 3
next loop we get
l=1
ss=3+(50-48)*10
so ss = 23
next loop
l=0
ss=23+(49-48)*100
so ss= 123
The loop breaks and we return an integer of value 123.
Hope this helps!