How to subtract integers from characters in C? - c++

Brian Kernighnan in his book Programming with C says
By definition, chars are just small integers, so char variables and
constants are identical to ints in arithmetic expressions.
Does this mean we can subtract char variable from int ??
I wrote a small piece of code:
#include <stdio.h>
main()
{
int a ;
int c;
a = 1;
c = 1 - '0' ;
printf("%d", c);
}
However it gives me output = -47...
What is that I'm doing wrong ?? Are the variables I assigned have the right type??

The output is to be expected. '0' is a char value that, since your compiler presumably uses the ASCII encoding, has value 48. This is converted to int and subtracted from 1. Which gives the value -47.
So the program does what it is expected to do, just not what you might hope it would do. As for what you are doing wrong, it is hard to say. I'm not sure what you expect the program to do, or what problem you are trying to solve.

The characters from '0'-'9'' have values 48-57 when converted to integer ('0' = 48, '1' = 49 etc). Read more about ASCII Values. When used in numerical calculation, first they are converted to int, so 1- '0' = 1-48 =-47.

You're mixing here the actual operation with the form of representation. printf outputs the data according to the specified format - integer in your case. If you want to print it as a character, switch %d with %c.

What you are doing is treating with the ASCII code of the chars, each char has an ASCII value assigned.
Now, playing a little with the ASCII of each char you can do things like:
int a;
a = 'a' - 'A' ;
printf("%d", a);
And get 32 as output, due to the ASCII value to 'a' = 97 and for 'A' = 65, then you have 97-65 = 32

I think this gives you more clear understanding...
#include <stdio.h>
main()
{
int a ;
a = 1;
printf("%d", char(a+48));
//or printf("%d", char(a+'0'));
}

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'.

Conversion from int to char failed and console prints weird symbol

I am having a weird issue and I don't know how to explain it. When I run this code it prints this symbol -> .
This is my code:
#include <iostream>
int main() {
int num = 1;
char number = num;
std::cout<<number<<std::endl;
system("PAUSE");
return 0;
}
I don't understand why. Normally it should convert the integer to char. I am using Dev C++ and my language standard is ISO C++11. I am programming for 4 years now and this is the first time I get something like this. I hope I explained my issue and if someone can help me I will be grateful.
Conversion from int to char failed
Actually, int was successfully converted to char.
Normally it should convert the integer to char.
That's what it did. The result of the conversion is char with the value 1.
Computers use a "character encoding". Each symbol that you see on the screen is encoded as a number. For example (assuming ASCII or compatible encoding) the value of 'a' character is 97.
A char with value of 1 is not the same as char with the value that encodes the character '1'. As such, when you print a character with value 1, you don't see the number 1, but the character that the value 1 encodes. In the ASCII and compatible encodings, 1 encodes a non-visible symbol "start of heading".
I wanted to print 1 as a char.
You can do it like this:
std::cout << '1' << '\n';
Then, since 4 years you seem to misunderstand what char is. It's not directly a character, but a number. It's the encoding that turns that number into a readable character.
Essentially, char i=1 is not the same as char i='1' (ascii table).

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'));
}

what does that mean, C programm for RLE

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.

C++ Convert Ascii Int To Char To Int

Im able to convert most things without a problem, a google search if needed. I cannot figure this one out, though.
I have a char array like:
char map[40] = {0,0,0,0,0,1,1,0,0,0,1,0,1... etc
I am trying to convert the char to the correct integer, but no matter what I try, I get the ascii value: 48/ 49.
I've tried quite a few different combinations of conversions and casts, but I cannot end up with a 0 or a 1, even as a char.
Can anyone help me out with this?
Thanks.
The ascii range of the characters representing integers is 48 to 57 (for '0' to '9'). You should subtract the base value 48 from the character to get its integer value.
char map[40] = {'0','0','0','0','0','1','1','0','0','0','1','0','1'...};
int integerMap[40];
for ( int i = 0 ;i < 40; i++)
{
integerMap[i] = map[i] - 48 ;
// OR
//integerMap[i] = map[i] - '0';
}
If the char is a literal, e.g. '0' (note the quotes), to convert to an int you'd have to do:
int i = map[0] - '0';
And of course a similar operation across your map array. It would also be prudent to error-check so you know the resulting int is in the range 0-9.
The reason you're getting 48/49 is because, as you noted, direct conversion of a literal like int i = (int)map[0]; gives the ASCII value of the char.