last character of a string in c++ using n.back() and casting - c++

my input is 12. Why is the output 50?
#include <iostream>
#include <string.h>
using namespace std;
int main() {
string n;
cin>>n;
cout << (int)n.back();
}

my input is 12. Why is the output 50?
Because the value that encodes the code unit '2' in the character encoding that is in use on your system happens to be 50.
If you wish to print the symbol that the code unit represents, then you must not cast to int type, and instead insert a character type:
std::cout << n.back();
If you wish to map a character representing '0'..'9' to the corresponding integer value, you can use character - '0'. Why this works: Regardless of what value is used to represent the digit '0', subtracting its own value from itself will produce the value 0 because z - z == 0. The other digits work because of the fact that all digits are represented by contiguous values starting with '0'. Hence, '1' will be represented by '0' + 1 and z + 1 - z == 1.

Related

Slicing string character correctly in C++

I'd like to count number 1 in my input, for example,111 (1+1+1) must return 3and
101must return 2 (1+1)
To achieve this,I developed sample code as follows.
#include <iostream>
using namespace std;
int main(){
string S;
cout<<"input number";
cin>>S;
cout<<"S[0]:"<<S[0]<<endl;
cout<<"S[1]:"<<S[1]<<endl;
cout<<"S[2]:"<<S[2]<<endl;
int T = (int) (S[0]+S[1]+S[2]);
cout<<"T:"<<T<<endl;
return 0;
}
But when I execute this code I input 111 for example and my expected return is 3 but it returned 147.
[ec2-user#ip-10-0-1-187 atcoder]$ ./a.out
input number
111
S[0]:1
S[1]:1
S[2]:1
T:147
What is the wrong point of that ? I am totally novice, so that if someone has opinion,please let me know. Thanks
It's because S[0] is a char. You are adding the character values of these digits, rather than the numerical value. In ASCII, numerical digits start at value 48. In other words, each of your 3 values are exactly 48 too big.
So instead of doing 1+1+1, you're doing 49+49+49.
The simplest way to convert from character value to digit is to subtract 48, which is the value of 0.
e.g, S[0] - '0'.
Since your goal is to count the occurrences of a character, it makes no sense to sum the characters together. I recommend this:
std::cout << std::ranges::count(S, '1');
To explain the output that you get, characters are integers whose values represent various symbols (and non-printable control characters). The value that represents the symbol '1' is not 1. '1'+'1'+'1' is not '3'.

How getchar() function output

I want to understand how is getchar() function is working here?
I read getchar() returns the next character from stdin, or EOF if the end of file is reached.
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
int decimal;
while(!isdigit(decimal=getchar()));
cout<<decimal;
}
I give input 25. It outputs 50. I don't understand why?
How is it giving 50.
getchar() reads a single character from the input stream and returns it's value. In your case, that is the character '2'. Most implementations (including yours it seems) use ASCII encoding where the character '2' has the value 50. The value assigned to decimal is therefore 50. Since decimal is an int, std::cout interprets it as a numeric value and prints it accordingly.
decimal is storing the first digit character it finds, which happens to be '2'. You're storing the value to an int, so cout outputs the ordinal value of decimal. The ASCII ordinal value of '2' is 50. You never even reached the 5 you entered.
Simple fix to make it display the character, not the ordinal value, would be to change the output code to:
cout << (char)decimal;
When you enter 25 it reads first character from this input. And first character is 2 here. ASCII value of 2 is 50. That's why you get 50 at the output.
If you want to see 2 at the output use like this
cout << (char) decimal << endl;
Here type-casting 50 into character. That is 2.
The C library function int getchar(void) gets a character (an unsigned char) from stdin.
Moreover, decimal is an integer type and isdigit(decimal) will check the character at ASCII decimal position.
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
int decimal;
while(!isdigit(decimal=getchar()));\\when you input 25. It first gets 2.
\\ 2 gets stored as 50 inside decimal
\\ isdigit() is called which returns true for 50 which is ASCII of 2 and while breaks
cout<<decimal; \\ 50 is printed here. Type cast it to print 2.
}

Char Subtraction in c++

I am fairly new to C++ and i have some trouble in understanding character subtraction in c++.
I had this code intially
char x='2';
x-='0';
if(x) cout << "More than Zero" << endl;
This returned More than Zero as output so to know the value of x i tried this code.
char x='2';
x-='0';
if(x) cout << x << endl;
And i am getting null character(or new line) as output.
Any help is appreciated.
According to the C++ Standard (2.3 Character sets)
...In both the source and execution basic character sets, the value of
each character after 0 in the above list of decimal digits shall be
one greater than the value of the previous.
So the codes of adjacent digits in any character set differ by 1.
Thus in this code snippet
char x='2';
x-='0';
if(x) cout << x << endl;
the difference between '2' and '0' (the difference between codes that represent these characters; for example in ASCII these codes are 0x32 and 0x30 while in EBCDIC they are 0xF2 and 0xF0 correspondingly) is equal to 2.
You can check this for example the following way
if(x) cout << ( int )x << endl;
or
if(x) cout << static_cast<int>( x ) << endl;
If you just write
if(x) cout << x << endl;
then the operator << tries to output x as a printable character image of the value 2 because x is of type char.
In C/C++ characters are stored as 8-bit integers with ASCII encoding. So when you do x-='0'; you're subtracting the ASCII value of '0' which is 48 from the ASCII value of '2' which is 50. x is then equal to 2 which is a special control character stating STX (start of text), which is not printable.
If you want to perform arithmetic on characters it's better to subtract '0' from every character before any operation and adding '0' to the result. To avoid problems like running over the range of the 8bit value I'd suggest to cast them on ints or longs.
char x = '2';
int tempVal = x - '0';
/*
Some operations are performed here
*/
x = tempValue % 10 + '0';
// % 10 - in case it excedes the range reserved for numbers in ASCII
cout << x << endl;
It's much safer to perform these operations on larger value types, and subtracting the '0' character allows you to perform operations independent on the ASCII encoding like you'd do with casual integers. Then you add '0' to go back to the ASCII encoding, which alows you to print a number.
You are substracting 48 (ascii char '0') to the character 50 (ascii '2')
50 - 48 = 2
if (x) ' true
In C++, characters are all represented by an ASCII code (see http://www.asciitable.com/)
I guess that doing :
'2' - '0'
is like doing
50 - 48 = 2
According to the ASCII table, the ASCII code 2 stands for start of text, which is not displayed by cout.
Hope it helps.
So what your code is doing is the following:
x = '2', which represents 50 as a decimal value in the ASCII table.
then your are basically saying:
x = x - '0', where zero in the ASCII table is represented as 48 in decimal, which equates to x = 50 - 48 = 2.
Note that 2 != '2' . If you look up 2(decimal) in the ASCII table that will give you a STX (start of text). This is what your code is doing. So keep in mind that the subtraction is taking place on the decimal value of the char.

Why was the C++ string converted to int?

In the following code, I can not understand why the string is converted to int in this way.
Why is it using a sum with 0 ?
string mystring;
vector<int> myint;
mystring[i+1]=myint[i]+'0';
This code converts an int (presumably a digit) to the character that represents it.
Since characters are sequential, and chars can be treated as integers, the character representing a certain digit can, in fact, be described by its distance from '0'. This way, 0 turns turn to the character '0', '5' is the character that is greater than '0' by five, and so on.
This is an efficient, old school and dangerous method to get a char representation of a single digit. '0' will be converted to an int containing its ASCII code (0x30 for '0') and then that is added to myint[i]. If myint[i] is 9 or lower, you can cast myint[i] to a char you will get the resulting digit as text.
Things will not go as expected if you add more than 9 to '0'
You can also get a number from its char representation :
char text = '5';
int digit = text - '0';
The '0' expression isn't string type, it's char type that stores characters of ASCII and also can represent numbers from 0 to 255. So, in arithmetic operations char behaves like integer type.
In C strings a represent as arrays of char: static (char str[N]) or dynamic (char *str = new char[n]). String literals puts into double quotes ("string").
So, '0' is char and "0" is char[1]

What is the logic behind this program?

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!