Use of s[i] - '0' [duplicate] - c++

This question already has answers here:
How do you convert char numbers to decimal and back or convert ASCII 'A'-'Z'/'a'-'z' to letter offsets 0 for 'A'/'a' ...?
(4 answers)
Closed 7 years ago.
The following code basically takes a string and converts it into an integer value. What I don't understand is why the int digit = s[i] - '0'; is necessary. Why can't it work by using int digit = s[i] instead? What purpose does the -'0' have?
int main(){
string s = "123";
int answer = 0;
bool is_negative = false;
if (s[0] == '-')
{
is_negative = true;
}
int result = 0;
for (int i = s[0] == '-' ? 1 : 0; i < s.size(); ++i)
{
int digit = s[i] - '0';
result = result * 10 + digit;
}
answer = is_negative ? -result : result;
cout << answer << endl;
system("pause");
}

Firstly, in your question title
the use of '0'
should be written as
the use of s[i] - '0'
That said, by subtracting the ASCII value of char 0 (represented as '0'), we get the int value of the digit represented in char format (ASCII value, mostly.)

It's because the value inside s[i] is a char type.
To convert the char '1' into an integer, you do '1' - '0' to get 1. This is determined by position in the ASCII table, char '0' is 48, while char '1' is 49.

The reason for the subtraction is that s[i] is, for example, '6'. The value '6' evaluates to 54 (the ascii code). The ASCII code of '0' is 48. So '6' - '0' = 6, which is the char value expressed as an int.

Related

I don't understand the process converting string to int [duplicate]

This question already has answers here:
Why does subtracting '0' in C result in the number that the char is representing?
(8 answers)
Closed 1 year ago.
Given the following code.
this problem is Leet Code 415.
string addStrings(string num1, string num2) {
string res;
int sum = 0;
int i = num1.size() - 1;
int j = num2.size() - 1;
while(i >= 0 && j >= 0)
{
sum += (num1[i--] - '0') + (num2[j--] - '0'); // this problem point
res.push_back(char(sum%10 + '0'));
sum = sum/10;
}
while(i >= 0)
{
sum += (num1[i--] - '0');
res.push_back(char(sum%10 + '0'));
sum = sum/10;
}
while(j >= 0)
{
sum += (num2[j--] - '0');
res.push_back(char(sum%10 + '0'));
sum = sum/10;
}
if(sum > 0)
res.push_back(char(sum%10 + '0'));
reverse(res.begin(), res.end());
return res;
}
I don't understand the process converting string to int.
Why is it a int when I subtract '0' from string?
If it doesn't change int, how is it possible to operate on strings?
In c++ characters can be implicitly cast to integers using their ASCII codes. I don't really want to spoil the fun of solving the given problem so i'll just provide a hint here:
Given a single digit number '2' and '4' with an ASCII code of 50 and 52 (decimal) respectively, subtracting '0' with an ASCII code of 48 from both numbers, you get the actual numerical values of the characters (50-48 = 2) and so on.
Have fun coding!
So the way ascii works is that consecutive numbers are following each other. If a string of characters only contain digits, you can get those digits by subtracting the value '0' from them. In ascii '0' = 0x30, '1' = 0x31 etc..
In your code num[i--] - '0' just checks "how far" you are from '0' in the ascii table, giving the correct digit if it is indeed a digit.
Also you don't convert string to anything (at least on the specific line). You access an element, which is a char that is an integer type in c++.

Logical error-encrypting a message in C++

the code should count each character. If the character is a number, it should count the previous character as much as the number.
So if the input is 'a', it should count 'a' once and assign it to acounter which now is equal to 1.
but if after 'a' is 3, it means 'aaa' and it should count 'a' three times and assign it to acounter which now is equal to 3.
Note: the program is for all of the alphabets but if this one isn't solved then what's the point of writing the rest?
I've tried put another loop exclusively for numbers but it didn't work.
char secret_message[1000];
int counter,number_counter;
int acounter=0;
gets(secret_message);
for (counter = 0 ; secret_message[counter] != NULL ; counter++)
{
if (secret_message[counter]=='a')
acounter++;
if (secret_message[counter] >= '0' && secret_message[counter] <= '9')
{
for(number_counter=1;number_counter<=secret_message[counter];number_counter++)
{
if (secret_message[counter-1]=='a')
acounter++;
}
}
}
cout<<endl<<"acounter is:"<<acounter;
if the input is a3 the output should be 3, but it's 52 !
You'll want to convert the digit from text to number, then use addition:
if (isdigit(secret_message[counter]))
{
const int value = secret_message[counter] - '0';
acounter += value;
}

C++:How to convert string into integer without using any built in functions [duplicate]

This question already has answers here:
How compiler is converting integer to string and vice versa
(3 answers)
Closed 7 years ago.
I am trying to convert a string to a integer and carry out some arithmetic after that.
char string[10];
If the string has only one word I can do this:
string[0]-'0'
How can I convert it into an integer if the string has more than one character.
Better to use a built-in function, but if you want to do it by hand, you need to loop through all of the characters in the string that are actually digits. Since this is in base-10, you simply multiply an accumulator by 10 every time through the loop:
int strToInt (const char *str) {
int accumulator = 0;
int sign = 1;
if (*str == '-') {
str++;
sign = -1;
}
while (*str >= '0' && *str <= '9') {
accumulator *= 10;
accumulator += *str - '0';
str++;
}
return accumulator * sign;
}
int i,ans;
char num[] = "5678";
int l = strlen(num);
ans = 0;
for(i=0;i<l;i++)
ans = ans*10 + (num[i]-'0');
printf("%d\n",ans);

Unary operations in C++

I came across a programming question of which I knew only a part of the answer.
int f( char *p )
{
int n = 0 ;
while ( *p != 0 )
n = 10*n + *p++ - '0' ;
return n ;
}
This is what I think the program is doing.
p is a pointer and the while loop is DE-refrencing the values of the pointer until it equals 0. However I don't understand the n assignment line, what is '0' doing? I am assuming the value of p is initially negative, that is the only way it will reach 0 after the increment.
You are confusing the number zero (none, nothing) with the character 0 (a circle, possibly with a slash through it). Notice that zero is in tick marks, so it's the character "0", not the number zero.
'0' - '0' = 0
'1' - '0' = 1
'2' - '0' = 2
...
So by subtracting the character zero from a digit, you get the number that corresponds to that digit.
So, say you have this sequence of digits: '4', '2', '1'. How do you get the number four-hundred and twenty-one from that? You turn the '4' into four. Then you multiply by ten. Now you have fourty. Convert the '2' into two and add it. Now you have fourty-two. Multiply by ten. Convert the '1' into one, and add, now you have four hundred and twenty one.
That's how you convert a sequence of digits into a number.
The n local variable accumulates the value of the decimal number that is passed to this function in the string. This is an implementation of atoi, without the validity checks.
Here is the workings of the loop body:
n = 10*n + *p++ - ‘0';
Assign to n the result of multiplying the prior value of n by ten plus the current character code at the pointer p less the code of zero; increment p after dereferencing.
Since digit characters are encoded sequentially, the *p-'0' expression represents a decimal value of a digit.
Let's say that you are parsing the string "987". As you go through the loop, n starts at zero; then it gets assigned the following values:
n = 10*0 + 9; // That's 9
n = 10*9 + 8; // That's 98
n = 10*98 + 7; // That's 987
It's poorly written, to say the least.
0) Use formatting!:
int f(char* p)
{
int n = 0;
while (*p != 0)
n = 10*n + *p++ - ‘0?;
return n;
}
1) ? there is syntactically invalid. It should probably be a ' as noted by chris (and your existing ‘ is wrong too, but that's probably because you copied it from a website and not a source file), giving:
int f(char* p)
{
int n = 0;
while (*p != 0)
n = 10 * n + *p++ - '0';
return n;
}
2) The parameter type isn't as contrained as it should be. Because *p is never modified (per our goals), we should enforce that to make sure we don't make any mistakes:
int f(const char* p)
{
int n = 0;
while (*p != 0)
n = 10 * n + *p++ - '0';
return n;
}
3) The original programmer was obviously allergic to readable code. Let's split up our operations:
int f(const char* p)
{
int n = 0;
for (; *p != 0; ++p)
{
const int digit = *p - '0';
n = 10 * n + digit;
}
return n;
}
4) Now that the operations are a bit more visible, we can see some independent functionality embedded in this function; this should be factored out (this is called reactoring) into a separate function.
Namely, we see the operation of converting a character to a digit:
int todigit(const char c)
{
// this works because the literals '0', '1', '2', etc. are
// all guaranteed to be in order. Ergo '0' - '0' will be 0,
// '1' - '0' will be 1, '2' - '0' will be 2, and so on.
return c - '0';
}
int f(const char* p)
{
int n = 0;
for (; *p != 0; ++p)
n = 10 * n + todigit(*p);
return n;
}
5) So now it's clear the function reads a string character by character and generates a number digit by digit. This functionality already exists under the name atoi, and this function is an unsafe implementation:
int todigit(const char c)
{
// this works because the literals '0', '1', '2', etc. are
// all guaranteed to be in order. Ergo '0' - '0' will be 0,
// '1' - '0' will be 1, '2' - '0' will be 2, and so on.
return c - '0';
}
int atoi_unsafe(const char* p)
{
int n = 0;
for (; *p != 0; ++p)
n = 10 * n + todigit(*p);
return n;
}
It's left as an exercise to the read to check for overflow, invalid characters (those that aren't digits), and so on. But this should make it much clearer what's going on, and is how such a function should have been written in the first place.
This is a string to number conversion function. Similar to atoi.
A string is a sequence of characters. So "123" in memory would be :
'1','2','3',NULL
p Points to it.
Now, according to ASCII, digits are encoded from '0' to '9'. '0' being assigned the value 48 and '9' being assigned the value 57. As such, '1','2','3',NULL in memory is actually : 49, 50, 51, 0
If you wanted to convert from the character '0' to the integer 0, you would have to subtract 48 from the value in memory. Do you see where this is going?
Now, instead of subtracting the number 48, you subtract '0', which makes the code easier to read.

Conversion between binary and decimal number

I woud like to ask, what bin-'0' means in this piece of code which convert binary number to decimal. Thanks.
#include <stdio.h>
#include <stdlib.h>
int main(){
char bin;
int dec = 0;
printf("Binary: \n");
bin = getchar();
while((bin != '\n')){
if((bin != '0') && (bin != '1')){
printf("Wrong!\n");
return 0;
}
printf("%c",bin-'0'); // ?
dec = dec*2+(bin-'0'); // ?
bin = getchar();
}
printf("Decimal: %d\n", dec);
return 0;
}
bin - '0' converts the ASCII value of bin to its integer value. Given bin = '1', bin - '0' = 1
This code is taking advantage of the fact that C++ chars are really just special ints. It's using getchar to take in a char that is either '0' or '1'. Now it needs to convert that into 0 or 1 (note that these are numbers, not chars). Given that the char '0' is one before '1', subtracting the value of char '0' from both will turn '0' into 0 and '1' into 1.
'0' - '0' = 0
'1' - '0' = 1