C++ gives random value when combining chars - c++

I have a string 039 and i have this following code
cout<<str2[1]+str2[0]+str2[2]<<endl;
I expect this to give me 309,but it gives me 156.How is that considering that separately all they give me 3 0 9?

It is because you are summing the characters / their underlying integral values together. If you want to output the characters themselves use the << operator, not the +. The characters and their underlying values are (assuming ASCII):
'3' 51
'0' 48
'9' 57
The expression of:
str2[1] + str2[0] + str2[2]
sums the characters together, it does not send them to standard output one by one, so the expression becomes:
51 + 48 + 57
resulting in 156. Use the operator<< instead:
#include <iostream>
#include <string>
int main() {
std::string str2 = "039";
std::cout << str2[1] << str2[0] << str2[2] << '\n';
}
As pointed out in the comments, character types are integral types and your char type probably covers the range from -127 to 127. This also assumes you are using ASCII encoding which maps the characters to values given above.

If str2[1] is char, then:
Char is just like int, but from -127 to 127(or 0 to 255). See ASCII codes.
Then if you do str2[1]+str2[0]+str2[2], you will get some ASCII code.
In c++ you can't do char+char and get 2 chars.
Do this:
cout<<str2[1]<<str2[0]<<str2[2]<<endl;

If you need retrieve result as a string use ostringstream :
#include <sstream>
std::ostringstream stream;
stream << str2[1] << str2[0]<< str2[2];
std::string res = stream.str();
std::cout <<"> " << res << std::endl;

Related

Totally unrelated result when multiplying two integers?

#include <iostream>
using std::cout;
using std::endl;
int main(void) {
std::string fx = "6x^2+6x+4";
int part1 = fx[0] * fx[3];
cout << fx[0] << endl;
cout << fx[3] << endl;
cout << part1;
}
So I have this string and fx[0] and fx[3] are obviously integers: when I print them to the console they print out just fine; however, part1 (their multiplication) equals some totally unrelated number? Can anyone help?
Here is the output:
6
2
2700
Your fx[0] and fx[3] variables are of type char (which is an integer type in C++). However, the actual values in those two elements of your fx string will be representations of the digits, 6 and 2, not the numerical values of those digits.
Very often, those representations will be ASCII codes (but that's not required); however, what is required is that the representations of the digits 0 thru 9 have contiguous, sequential values. Thus, by subtracting the value of the digit, 0, we can convert to their numerical representations.
In your case, the following line will do the conversion:
int part1 = (fx[0]-'0') * (fx[3]-'0');
The reason why you see the correct values when printing fx[0] and fx[3] is because the version of the cout << operator that takes a char argument is designed to print the represented character (not its 'ASCII' code); however, the cout << operator for an int type (like your part1) will print the actual value represented internally. (Try changing one of your lines to cout << (int)fx[0] << endl; to see the difference.)
P.S. Don't forget the #include <string> header – some implementations do that implicity inside the <iostream> header, but don't rely on that!
well, first of all, string::operator[] returns a char... then, a char can be casted to an int, and the cast works checking the ID in the ASCII table (in your case)
In ASCII, the ID of "6" and "2" are respectively 54 and 52 (you can check it here for example)... so your program is taking the two char, casting them to int, and multiplying them (54 * 50 = 2700)
If you need to interpret those as the integer value they represent, you can check this answer:
int val = '6' - '0'; // val == 6
Characters are values representing glyphs from some representation, usually the ASCII table. The numeric value of a character is not the same as the glyph that is printed on the screen. To convert a numeric-looking char to an actual "0-based" numeric value, subtract '0' from your char value.
(fx[3]-'0']) will be the numeric value of character represented at position 3.
You are multiplying character types. so the characters '6' and '2' will converted to its integer values 54 and 50 respectively then multiplication is applied. This works based on C++ type conversion rule. Then you will get 2,700. Try the modified sample code
#include <iostream>
using std::cout;
using std::endl;
int main(void) {
std::string fx = "6x^2+6x+4";
int part1 = fx[0] * fx[3];
cout << fx[0] << endl;
cout << fx[3] << endl;
cout << part1;
cout << std::endl;
cout << (int)fx[0] << " " << (int)fx[3] << std::endl;
}
And the results
6
2
2700
54 50

When i run the following code adding str.front() + str.back it gives me 200 but why?

string str = "abcdefg";
cout << str.back() + str.front();
C++ console:
200
#include <iostream>
int main() {
std::string str = "abcdefg";
for(int v : str) {
std::cout << v << " " << static_cast<char>(v) << "\n";
}
}
Possible output:
97 a // front()
98 b
99 c
100 d
101 e
102 f
103 g // back()
97+103 = 200
When i run the following code adding str.front() + str.back it gives me 200 but why?
Characters are encoded as integers. char is an integer type. When operands of an arithmetic operation (such as addition) are integer types smaller than int, those operands are promoted to int, which is also the result type of the expression. That is why the output is not an encoded character, but decimal representation of the integer instead.
Why the value 200, well it just so happens that in the character encoding of your system, the value that represents 'a' and the value that represents 'g' total 200 when added together.
You're adding two chars, which results in an integer.
If you want to combine the two characters to a string, you have to give at least one of them string type, e.g. :
cout << str.back() + string{str.front()};
or
cout << str.back() + str.substr(0, 1);
If you just want to output two characters, though - you can simply output them one at a time:
cout << str.back() << str.front();

String and integer multiplication in C++

I wrote the following code
#include <iostream>
#define circleArea(r) (3.1415*r*r)
int main() {
std::cout << "Hello, World!" << std::endl;
std::cout << circleArea('10') << std::endl;
std::cout << 3.1415*'10'*'10' << std::endl;
std::cout << 3.1415*10*10 << std::endl;
return 0;
}
The output was the following
Hello, World!
4.98111e+08
4.98111e+08
314.15
The doubt i have is why is 3.1415 * '10'*'10' value 4.98111e+08. i thought when i multiply a string by a number, number will be converted to a string yielding a string.Am i missing something here?
EDIT: Rephrasing question based on comments, i understood that single quotes and double are not same. So, '1' represents a single character. But, what does '10' represent
'10' is a multicharacter literal; note well the use of single quotation marks. It has a type int, and its value is implementation defined. Cf. "10" which is a literal of type const char[3], with the final element of that array set to NUL.
Typically its value is '1' * 256 + '0', which in ASCII (a common encoding supported by C++) is 49 * 256 + 48 which is 12592.

Take two hex characters from file and store as a char with associated hex value

I'd like to take the next two hex characters from a stream and store them as the associated associated hex->decimal numeric value in a char.
So if an input file contains 2a3123, I'd like to grab 2a, and store the numeric value (decimal 42) in a char.
I've tried
char c;
instream >> std::setw(2) >> std::hex >> c;
but this gives me garbage (if I replace c with an int, I get the maximum value for signed int).
Any help would be greatly appreciated! Thanks!
edit: I should note that the characters are guaranteed to be within the proper range for chars and that the file is valid hexadecimal.
OK I think dealing with ASCII decoding is a bad idea at all and does not really answer the question.
I think your code does not work because setw() or istream::width() works only when you read to std::string or char*. I guess it from here
How ever you can use the goodness of standard c++ iostream converters. I came up with idea that uses stringstream class and string as buffer. The thing is to read n chars into buffer and then use stringstream as a converter facility.
I am not sure if this is the most optimal version. Probably not.
Code:
#include <iostream>
#include <sstream>
int main(void){
int c;
std::string buff;
std::stringstream ss_buff;
std::cin.width(2);
std::cin >> buff;
ss_buff << buff;
ss_buff >> std::hex >> c;
std::cout << "read val: " << c << '\n';
}
Result:
luk32#genaker:~/projects/tmp$ ./a.out
0a10
read val: 10
luk32#genaker:~/projects/tmp$ ./a.out
10a2
read val: 16
luk32#genaker:~/projects/tmp$ ./a.out
bv00
read val: 11
luk32#genaker:~/projects/tmp$ ./a.out
bc01
read val: 188
luk32#genaker:~/projects/tmp$ ./a.out
01bc
read val: 1
And as you can see not very error resistant. Nonetheless, works for the given conditions, can be expanded into a loop and most importantly uses the iostream converting facilities so no ASCII magic from your side. C/ASCII would probably be way faster though.
PS. Improved version. Uses simple char[2] buffer and uses non-formatted write/read to move data thorough the buffer (get/write as opposed to operator<</operator>>). The rationale is pretty simple. We do not need any fanciness to move 2 bytes of data. We ,however, use formatted extractor to make the conversion. I made it a loop version for the convenience. It was not super simple though. It took me good 40 minutes of fooling around to figure out very important lines. With out them the extraction works for 1st 2 characters.
#include <iostream>
#include <sstream>
int main(void){
int c;
char* buff = new char[3];
std::stringstream ss_buff;
std::cout << "read vals: ";
std::string tmp;
while( std::cin.get(buff, 3).gcount() == 2 ){
std::cout << '(' << buff << ") ";
ss_buff.seekp(0); //VERY important lines
ss_buff.seekg(0); //VERY important lines
ss_buff.write(buff, 2);
if( ss_buff.fail() ){ std::cout << "error\n"; break;}
std::cout << ss_buff.str() << ' ';
ss_buff >> std::hex >> c;
std::cout << c << '\n';
}
std::cout << '\n';
delete [] buff;
}
Sample output:
luk32#genaker:~/projects/tmp$ ./a.out
read vals: 0aabffc
(0a) 0a 10
(ab) ab 171
(ff) ff 255
Please note, the c was not read as intended.
I found everything needed here http://www.cplusplus.com/reference/iostream/
You can cast a Char to an int and the int will hold the ascii value of the char. For example, '0' will be 48, '5' will be 53. The letters occur higher up so 'a' will be cast to 97, 'b' to 98 etc. So knowing this you can take the int value and subtract 48, if the result is greater than 9, subtract another 39. Then char 0 will have been turned to int 0, char 1 to int 1 all the way up to char a being set to int 10, char b to int 11 etc.
Next you will need to multiply the value of the first by 16 and add it to the second to account for the bit shift. Using your example of 2a.
char 2 casts to int 50. Subtract 48 and get 2. Multiply by 16 and get 32.
char a casts to int 97. Subtract 48 and get 49, this is higher than 9 so subtract another 39 and get 10. Add this to the end result of the last one (32) and you get 42.
Here is the code:
int HexToInt(char hi, char low)
{
int retVal = 0;
int hiBits = (int)hi;
int loBits = (int)low;
retVal = Convert(hiBits) * 16 + Convert(loBits);
return retVal;
}
int Convert(int in)
{
int retVal = in - 48;
//If it was not a digit
if(retVal > 10)
retVal = retVal - 7;
//if it was not an upper case hex didgit
if(retVal > 15)
retVal = retVal - 32;
return retVal;
}
The first function can actually be written as one line thus:
int HexToInt(char hi, char low)
{
return Convert((int)hi) * 16 + Convert((int)low);
}
NOTE: This only accounts for lower case letters and only works on systems that uses ASCII, i.e. Not IBM ebcdic based systems.

Why does my string get empty values appended to it when subtracting characters?

I am attempting to solve a problem from topcoder.com and it's driving me crazy. I am learning C++ after a long break from C and am having trouble with strings.
The purpose of the program is to decode a string of 0s and 1s that has gone through an encryption algorithm that consists of adding each adjacent digit to the digit in question.
So 010111 becomes 112232 (LSB and MSB are considered to have zeros next to them). Below is my algorithm to decode the string:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class BinaryCode {
public:
vector<string> decode(string message);
};
vector<string> BinaryCode::decode(string message) {
vector<string> decoded(2);
int i;
string myTempString;
myTempString.append("0");
myTempString.append(1,message[0] - myTempString[0]);
for(i=2; i<message.size(); i++) {
myTempString.append(1,message[i-1] - myTempString[i-1] - myTempString[i-2]);
}
decoded[0] = myTempString;
myTempString = "";
myTempString.append("1");
myTempString.append(1,message[0] - myTempString[0]);
for(i=2; i<message.size(); i++) {
myTempString.append(1, message[i-1] - myTempString[i-1] - myTempString[i-2]);
}
decoded[1] = myTempString;
return decoded;
}
int main () {
string message("123210122");
BinaryCode *code = new BinaryCode;
vector<string> result = code->decode(message);
cout << "Decoded strings are "+result[0]+" and "+result[1];
getchar();
return 0;
}
The output is nonsense:
Decoded strings are 01
This is just a guess, since you don't show what output you're getting, but it looks like you're doing math on the character values and ending up with characters in the control range. For example, '1' - '0' is not '1' (character 49), it is 1, or Control-A. This is not printable and will typically be invisible in the output. Similarly, '1' + '2' is 49 + 50, or 99, which is 'c'. C++ is not going to magically convert these characters to integers for you. Hopefully this will give you the information you need to fix your code.
A character is an 8-bit integral type. It has the special property that, when printed, it will appear as the character that matches the ASCII value that it contains.
For example:
int valueAsInt = 65;
char valueAsChar = valueAsInt;
std::cout << valueAsChar << "\n";
valueAsInt = 'A';
std::cout << valueAsInt << "\n";
A
65
Take the value of the character literal '0'. This corresponds to the ASCII value 48. '1' is 49, etc.
If you subtract 48 from 49, you get 1. But that's not what you're looking for.
The ASCII value 1 corresponds to a non-printable character, called "start of heading". It was once used on old printers as a sort of markup. It would not print, but it would modify how further characters are printed.
When you subtract one numeric character from another, you get a delta, not a printable character. To turn this delta back into a printable character, you have to add it to a base character:
char value = '5' - '3';
value += '0';
std::cout << "5 - 3 = " << value << "\n";
5 - 3 = 2
So, your code such as message[0] - myTempString[0] must be changed to message[0] - myTempString[0] + '0' in order to work the way you intend it to.