The task is to add a numerical value to all characters in the English alphabet and then by entering a word in the program, it should calculate its value. Anybody knows how this can be done?
If you don't care about the specific mapping from characters to integers, you can simply assign to an int:
char c = 'A';
int i = c;
On many architectures, this will map A to 65, B to 66 and so on.
To map an entire word to an integer, simply loop over the entire word and add the integers up. Your course should already have covered how to write a loop that inspects each character of a string.
So here is just some pseudo-code to give you the general idea of what I'm talking about:
int sum = 0
for each c in word
sum += c
You do know that you can add ints to C++ chars, do you?
char a = 'A';
char b = a + 1;
int b_int = b;
cout << b << " " << b_int;
//should print
// 'b' 66
//or something like that
Chars in C are just (byte-sized) integers, under the hood
Related
This question already has answers here:
Why does subtracting '0' in C result in the number that the char is representing?
(8 answers)
Closed 10 months ago.
while solving a leetcode challange , I stumbled upon various solutions that were adding and subtracting '0' for successful submission and I have no idea why . any help? I mostly do linked list and array so this problem is quite new to me .
class Solution {
public:
string addBinary(string a, string b) {
string result;
int i=a.size()-1;
int j=b.size()-1;
int carry = 0;
while(i>=0 || j>=0|| carry)
{
if(i>=0)
{ carry += a[i] - '0';//like here
i--;}
if(j>=0)
{ carry += a[j] - '0';//here
j--;
}
result += (carry%2 + '0'); //and here as well
carry = carry/2;
}
reverse(result.begin(),result.end());
return result;
}
};
In C++, '0' is a character literal.
The fundamental reason why/how a[i] - '0' works is through promotion. This is because:
arithmetic operators do not accept types smaller than int as arguments, and integral promotions are automatically applied after lvalue-to-rvalue conversion, if applicable
In particular when you wrote:
a[i]-'0'
This means
both a[i] and '0' will be promoted to an int. And so the result will be an int.
Let's looks at some example for more clarifications:
char c1 = 'E';
char c2 = 'F';
int result = c1 + c2;
Here both c1 and c2 will be promoted to an int. And the result will be an int. In particular, c1 will become(promoted to) 69 and c2 will become(promoted to) 70. And so result will be 69 + 70 which is the integer value 139.
This also makes the program more portable than using magic numbers.
Also note that the C++ Standard (2.3 Character sets) guarantees that:
...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.
For example, say we have:
std::string str = "123";
int a = str[0] - '0'; //the result of str[0] - '0' is guaranteed to be the integer 1
int b = str[1] - '0'; //the result of str[1] - '0' is guaranteed to be the integer 2
int c = str[2] - '0'; //the result of str[2] - '0' is guaranteed to be the integer 3
Lets consider the statement int a = str[0] - '0';:
Here both str[0] and 0 will be promoted to int. And the final result that is used to initialize variable a on the left hand side will be the result of subtraction of those two promoted int values on the right hand side. Moreover, the result is guaranteed to be the integer 1.
Similarly, for statement int b = str[1] - '0';:
Here both str[1] and 0 will be promoted to int. And the final result that is used to initialize variable b on the left hand side will be the result of subtraction of those two promoted int values on the right hand side. Moreover, the result is guaranteed to be the integer 2.
And similarly for variable c.
It seems to be converting strings' characters to its numeric values. For instance, if you define "char c = '0';", you had indeed stored the ASCII code (or equivalent string encoding) of the char '0' in variable c, not the value zero itself. So to get the actual numeric value out of the ASCII code, you have to subtract by the ASCII code from the char '0'.
Remember that strings are a sequence of numeric values, i.e., integers representing characters, using the ASCII Table or equivalent, depending on the string encoding being used (Unicode, etc...).
Please note the actual characters' numeric values will depending on the actual encoding being used. The most known and basic Encoding is probably ASCII, which does not support languages other than the original english. For international purposes, the most common nowadays is UNICODE UTF-8, which uses basically the same codes used by ASCII for plain English usual characters, but other more complicated encodings exist.
And, as correctly noted by Anoop Rana in the other answer to this question, the C++ standard guarantees the numeric values will be in a sequence in any encoding. So, by using this technique, you avoid magic numbers that would make your code work just with specific encodings.
Here goes a didactic code that may help:
#include <iostream>
#include <string>
using namespace std;
int main()
{
const string str = "5";
cout << "char: " << str << endl;
cout << "ASCII char's value: " << (int)str[0] << endl;
cout << "ASCII char's value of the character '0' is: " << ((int)'0') << endl;
cout << "Value represented by the ASCII code " << str[0] <<
" is the binary value " << (int)str[0] << "-" << ((int)'0') <<
"=" << (str[0] - '0') << endl;
return 0;
}
The output is:
char: 5
ASCII char's value: 53
ASCII char's value of the character '0' is: 48
Value represented by the ASCII code 5 is the binary value 53-48=5
The ASCII table code can be consulted here:
https://www.asciitable.com/
By the way, I think there may be a bug in your code, since parameter b is not being used. Maybe the second 'if' should be taking the value of b instead of a?
My requirement is to join two characters. For example
int main()
{
char c1 ='0';
char c2 ='4';
char c3 = c1+c2;
cout<< c3;
}
The value which I am expecting is 04. But what I am getting is d.
I know that char is single byte. My requirement is that in the single Byte of C3 is possible to merge/join/concat the c1,c2 and store the value as 04
A char is not a string. So you can first convert the first char to a string and than add the next ones like:
int main()
{
char c1 ='0';
char c2 ='4';
auto c3 = std::string(1,c1)+c2;
std::cout<< c3;
}
What is "magic" std::string(1,c1):
It uses the std::string constructor of the form: std::string::string (size_t n, char c);. So it "fills" the string with one single character of your given c1 which is the 0.
If you add chars you get the result of adding the numeric value of it which is:
int main() {
std::cout << (int)c1 << std::endl;
std::cout << (int)c2 << std::endl;
std::cout << (int)c1+c2 << std::endl;
std::cout << char(c1+c2) << std::endl;
}
The numeric value as int from 0 is 48, from 4 it is 52. Add both you get 100. And 100 is a d in ascii coding.
What you want is called a string of characters. There are many ways to create that in C++. One way you can do it is by using the std::string class from the Standard Library:
char c1 = '0';
char c2 = '4';
std::string s; // an empty string
s += c1; // append the first character
s += c2; // append the second character
cout << s; // print all the characters out
A char is no more than an integral type that's used by your C++ runtime to display things that humans can read.
So c1 + c2 is a instruction to add two numbers, and is an int type due to the rules of type conversions. If that's too big to fit into a char, then the assignment to c3 would have implementation-defined results.
If you want concatenation, then
std::cout << ""s + c1 + c2;
is becoming, from C++11's user defined literals, the idiomatic way of doing this. Note the suffixed s.
Each char in C (and C++) has the length of one byte. What you are doing is adding the actual byte values:
'0' = 0x30
'4' = 0x34
-> '0' + '4' = 0x30 + 0x34 = 0x64 = 'd'
If you want to concatenate those two you will need an array:
int main()
{
char c1 ='0';
char c2 ='4';
char c3[3] = {c1,c2,0}; // 0 at the end to terminate the string
cout<< c3;
return 0;
}
Note that doing those things with chars is C but not C++. In C++ you would use a string, just as Klaus did in his answer.
Basics first
In C++ and C, a string ends with '\0' which is called null character.
Presence of this null character at the end differentiates between a string and char array. Otherwise, both are contigous memory location.
While calculating string.length() not counting the null character at the end is taken care.
Joining/Concatenating two characters
If you join two character using + operator, then handling the null character in both strings end will be taken care.
But if you join two char with + operator and wish to see it as an string, it will not happen, because it has no null character at the end.
See the example below:
char c1 = 'a';
char c2 = 'b';
string str1 = c1 + c2;
cout << str1; // print some garbled character, as it's not valid string.
string str2; // null initialization
str2 = str2 + c1 + c2;
cout << str2; // prints ab correctly.
string s1 = "Hello";
string s2 = "World";
string str3 = s1 + s2;
cout << str3; //prints Hello World correctly.
string str4 = s1 + c1;
cout << str4; //prints Hello a correctly.
What you named "joining" is actually arithmetics on char types, which implicitly promotes them to int. The equivalent integer value for a character is defined by the ASCII table ('0' is 48, '4' is 52, hence 48 + 52 = 100, which finally is 'd'). You want to use std::string when concatenating textual variables via the + operator.
You can do somthing like that:
#include <vector>
#include <iostream>
using namespace std;
int main()
{
char a = '0';
char b = '4';
vector<char> c;
c.push_back(a);
c.push_back(b);
cout << c.data() << endl;
return 0;
}
Simple addition is not suitable to "combine" two characters, you won't ever be able to determine from 22 if it has been composed of 10 and 12, 11 and 11, 7 and 15 or any other combination; additionally, if order is relevant, you won't ever know if it has been 10 and 12 or 12 and 10...
Now you can combine your values in an array or std::string (if representing arbitrary 8-bit-data, you might even prefer std::array or std::vector). Another variant is doing some nice math:
combined = x * SomeFactorLargerThanAnyPossibleChar + y;
Now you can get your two values back via division and modulo calculation.
Assuming you want to encode ASCII only, 128 is sufficient; considering maximum values, you get: 127*128+127 == 127*129 == 2^14 - 1. You might see the problem with yourself, though: Results might need up to 14 bit, so your results won't fit into a simple char any more (at least on typical modern hardware, where char normally has eight bits only – there are systems around, though, with char having 16 bits...).
So you need a bigger data type for:
uint16_t combined = x * 128U + y;
//^^
Side note: if you use 256 instead, each of x and y will be placed into separate bytes of the two of uint16_t. On the other hand, if you use uint64_t and 127 as factor, you can combine up to 9 ASCII characters in one single data type. In any case, you should always use powers of two so your multiplications and divisions can be implemented as bitshifts and the modulo calculations as simple AND-operation with some appropriate mask.
Care has to be taken if you use non-ASCII characters as well: char might be signed, so to prevent unwanted effects resulting from sign extension when values being promoted to int, you need to yet apply a cast:
uint16_t combined = static_cast<uint8_t>(x) * 128U + static_cast<uint8_t>(y);
Since a basic char doesn't have operator+ to concatenate itself with another char,
What you need is a representation of a string literal using std::string as suggested by others
or in c++17, you can use string_view,
char array[2] = {'0', '4'};
std::string_view array_v(array, std::size(array));
std::cout << array_v; // prints 04
https://github.com/bite-rrjo/STG-char-v2/blob/main/stg.h
without external libraries it would be like this
#include "iostream"
#include "lib-cc/stg.h"
using namespace std;
int main(){
// sum two char
char* c1 = "0";
char* c2 = "4";
stg _stg;
_stg = c1;
_stg += c2;
cout << _stg() << endl;
// print '04'
}
Usually, I access an array in C++ by the syntax foo[2], where 2 is the index of an array.
In the below code. I didn't understand how this code is giving output and access this array by index 'b', 'c'. I am confused it is array index or something else.
int count[256] = {0};
count['b'] = 2;
cout << count['b'] << endl; //output 2
cout << count['c'] << endl; //output 0
Output
2
0
Remember that in c++ characters are represented as numbers. Take a look at this ascii table. http://www.asciitable.com
According to this the character 'b' is represented 98 and 'c' as 99. Therefore what your program is really saying is...
int count[256] = {0};
count[98] = 2;
cout << count[98] << endl; //output 2
cout << count[99] << endl; //output 0
Also incase you don't know saying an array = {0} means zero initialize every value so that is why count['c'] = 0.
In C/C++ there is not 8 bit / 1 byte integer. We simply use the char type to represent a single (signed or unsigned) byte and you can even put signed and unsigned infront of the char type. Char really is just another int type which we happen to use to express characters. You can also do the following.
char b = 98;
char c = 99;
char diff = c - b; //diff is now 1
Type char is actually an integral type. Every char value represented by a character literal has an underlying integral value it corresponds to in a given code page, which is probably an ASCII table. When you do:
count['b'] = 2;
you actually do:
count[98] = 2;
as character 'b' corresponds to an integral value of 98, character 'c' corresponds to an integral value of 99 and so on. To illustrate, the following statement:
char c = 'b';
is equivalent of:
char c = 98;
Here c has the same underlying value, it's the representation that differs.
Because characters are always represented by integers in the computer, it can be used as array indices.
You can verify by this:
char ch = 'b';
count[ch] = 2;
int i = ch;
cout << i << endl;
cout << count[i] << endl;
Usually the output is 98 2, but the first number may vary depending on the encoding of your environment.
Let's say, we have:
char x = 'a';
int y = 1;
So, if you run:
std::cout << x + y;
It prints 98 instead of 'b'. As i see from here
<<operator has only int parameter implementation.
From now on i have 2 questions:
After char + int operation what type is returned?
Why there is no char parameter implementation, but std::cout << x still works as expected and prints char value?
Thanks to Fefux, Bo Persson and Matti Virkkunen answers are:
From CPP Reference: Implicit conversions:
arithmetic operators do not accept types smaller than int as
arguments, and integral promotions are automatically applied after
lvalue-to-rvalue conversion, if applicable.
So return type of x + y is int.
std::cout has a operator<<(char) as a non-member.
As you probably know, C++ is backward compatible with C.
Both C & C++ treat chars like ints.
You may consider this a flaw of the language, but on the contrary, this is very handy.
Suppose you want to convert a capital letter to the corresponding small letter. Since any capital letter has an ASCII code 32 below the corresponding small letter, this is as simple as this:
char c = 'A';
std::cout << (char) (c + 32); // output: 'a'
Inversely you can convert from small letter to capital letter:
char c = 'a';
std::cout << (char) (c - 32); // output: 'A'
>The character 'b' is char('a'+1),'c' is char('a'+2),etc. Use a loop to write out a table of characters with their corresponding integer values.
I cannot finish this exercise because of this error.
error: lvalue required as increment operand
for(char a='a'; a<24; ++a)
{
cout<<char('a'++);
}
The loop body will never execute with the controlling expression a < 24 because you have initialized variable a with character a and all printable characters are not less than ASCII value 32.
Try this:
for(char a='a'; a < 'a' + 24; ++a)
{
cout << a;
}
I think you would be less confused if you named your variable letter instead of a, because it only represents the letter 'a' at the very beginning.
for(char letter='a'; letter<24; ++letter)
{
cout<<char('a'++);
}
I'm going to assume you actually want to print out the entire alphabet, not just the first 24 letters.
It looks from here like you tried to do a mix of two possible approaches. In the first approach, you increment a char from a to z with each iteration of the for loop and print it out each time. In the second approach, you increment some offset from 0 to 25 and print out 'a' + offset.
You mix these two approaches up in the first line. You're starting the loop with letter set to 'a', which you do not know the numerical value of. You then compare letter to see if it is less than 24. Well in any ASCII-compatible character set, the character 'a' has value 97, so this condition will never pass.
You then misuse ++ on the cout line. The ++ operator attempts to modify its operand, yet 'a' is a literal and so cannot be modified. Have a look at what your assignment told you. You can do 'a' + 1 to get 'b', for example, so this assumes you have an offset (which you don't with your current approach).
So to repeat, you have two options. First: keep letter as a char starting at 'a' and fix the condition so that it checks if letter is less than or equal to the value of 'z' and then just print out letter. Second: change letter to offset and start it off at 0 and increment it while it is less than 26, and then print out 'a' + offset.
Note, however, that both of these approaches assume that the letters have consecutive values in the execution character set. This is not necessarily true.
The ++ operator is a "hidden assignment" (the operand's value is changed by it). But you can only assign to variables, which 'a' is not.
I know this has been closed for a while but since the exercise was about while loops and not for loops, I thought I would offer my solution. I'm just going through the book myself and someone in the future might stumble over this.
int i = 0;
char n = 'a'; // this will list the alphabet
int conv = 0;
conv = n; // this converts the alphabet into integer
while (i < 26) { // starts from 0 and goes to 25
cout << char(n + i) << '\t' << conv + i << '\n';
++i;
}
You may use the following: (http://ideone.com/akwGhl)
#include <iostream>
int main()
{
for (char c = 'a'; c <= 'z'; ++c) {
std::cout << "letter " << c << " has value " << int(c) << std::endl;
}
return 0;
}
hey through troubleshooting i obtained a sample that worked , i have yet to perfectly understand how my code works but as the solutions that were proposed to me here seemed too technical for my level i figured that i should publish mine
#include"header files . h"//i use the libraries given in the book
int main () {
char a ='a';
int i = 0 ;
while (i <= 25)//for (i = 0 ; i <= 25 ; i++)
//for those who used for
{
cout << a << '\t' << 'a' + i << endl;
a += 1; // augments the character value of a to b ... then to z
i++; // augments the value of i allowing us thus to make the augmentation,if you are using the for structure do not put I in your code
}
}