Unexpected result from ternary operator - c++

I am trying to understand how the ternary operator works in C++.
I expect to see the same output for both print statements, yet the second print statement outputs 49.
Why is this?
#include <iostream>
using namespace std;
int main()
{
int test = 0;
cout << "First character " << '1' << endl;
cout << "Second character " << (test ? 3 : '1') << endl;
return 0;
}
Output:
First character 1
Second character 49

'1' got converted to an integer which represented the ASCII code for '1'. The ternary operator is supposed to have two values of the same type. You can not have 3 (an integer) and '1' (a char). That's why the conversion took place. If the implicit conversion could not have happened then a compiler error would have been generated.

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

Strange symbols printing in C++ instead of array content [duplicate]

I am working on below code:
#include<iostream>
#include<stdio.h>
using namespace std;
main() {
unsigned char a;
a=1;
printf("%d", a);
cout<<a;
}
It is printing 1 and some garbage.
Why cout is behaving so?
cout << a is printing a value which appears to be garbage to you. It is not garbage actually. It is just a non-printable ASCII character which is getting printed anyway. Note that ASCII character corresponding to 1 is non-printable. You can check whether a is printable or not using, std::isprint as:
std::cout << std::isprint(a) << std::endl;
It will print 0 (read: false) indicating the character is non-printable
--
Anyway, if you want your cout to print 1 also, then cast a to this:
cout << static_cast<unsigned>(a) << std::endl;
I had a similar issue here that I've long forgotten about. The resolution to this problem with iostream's cout can be done like this:
#include<iostream>
#include<stdio.h>
main() {
unsigned char a;
a=1;
printf("%d", a);
std::cout<< +a << std::endl;
return 0;
}
instead of casting it back to another type if you want cout to print the unsigned char value as opposed to the ascii character. You need to promote it.
If you noticed all I did was add a + before the unsigned char. This is unary addition that will promote the unsigned char to give you the actual number representation.
User Baum mit Augen is responsible for reminding me of this solution.
You need to typecast a as integer as cout<< (int)(a);. With this you will observe 1 on the output. With cout << a;, the print will be SOH (Start of Heading) corresponding to ascii value of 1 which can't be printed and hence, some special character is observed.
EDIT:
To be more accurate, the cout statement should be cout << static_cast<unsigned>(a) as Nawaz has mentioned.
The C compiler has its own way of defining the type of the printed output, because you can specify the type of the output.
Ex:
uint8_t c = 100;
printf("%d",c);
so you can also print c as an int by %d, or char %c, string %s or a hex value %x.
Where C++ has its own way too, the cout prints the 8-bit values as a char by default. So, you have to use specifiers with the output argument.
You can either use:
a + before the name of the output argument
uint8_t data_byte = 100;
cout << "val: " << +data_byte << endl;
use a function cast unsigned(var); like,
uint8_t data_byte = 100;
cout << "val: " << unsigned(data_byte) << endl;
printf("%u",a);
its so simple try it

Problem with comparison between pointer and integer C++

I've been getting error messages saying
[Error] ISO C++ forbids comparison between pointer and integer [-fpermissive]
and don't know how to fix it.
I've searched stackoverflow for people with same issues, but only came up with this: c++ compile error: ISO C++ forbids comparison between pointer and integer which didn't answer my question. What also confused me is that the error is on line indicated by the HERE comment, which is the if statement, but I don't see any integers in the condition part.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
int main() {
char in[100];
gets(in);
int len = strlen(in);
std::string s(in);
int count = 0;
for (int i = 0; i < len; i++) {
if (s.at(i) == " ") { // <-- HERE
count += 1;
}
}
cout << count;
}
Say the input is Hello World, I am expecting output to be 1, but I didn't get any output.
The expression " " is a string literal with type const char [2].
The expression s.at(i) returns a char&.
So, s.at(i) == " " is trying to find an equality operator taking
char& on the left and a reference to the literal array const char(&)[4] on the right.
It finds one or more candidates for operator==, but the argument types don't match any exactly, so next it tries the implicit conversion sequences - this is where the char& undergoes integral promotion to int, and the array decays to const char*.
It still doesn't find a match with these, and gives up, but that explains why it has int and const char * arguments when the error is emitted.
All that is a long way of saying that you write character literals like ' ' in C++. They're not just a string of length 1 as in some other languages (and you can't write strings with single quotes at all).
Change the if statement
if (s.at(i) == ' ') {
count += 1;
}
since s.at(i) returns char&, " " is a string, and ' ' is a char.
The problem is that " " is a string literal not a character! A character literal would be ' '.
The error is a bit misleading, because " " is acutally a const char*.
C++ differentiates between character strings and single characters in the literals by different quoting symbols (" vs '). The " " in your code is the string literal that contains one space, a single space character would be written as ' '. The function std::string::at returns a single character.
A small example will show you how the compiler looks on that
#include <iostream>
#include <string>
#include <typeinfo> // for typeid
using namespace std;
int main() {
string s = "Hello, world!";
cout << typeid(" ").name() << endl;
cout << typeid(' ').name() << endl;
cout << typeid(s.at(0)).name() << endl;
return 0;
}
see online demo of above code.
But, to be precise, identical types aren't required for comparisons in C++, but the types need to be compatible. Pointers (string literals are considered constant pointers to characters, in fact pointing to the first character in the literal) and integers (to which char is promoted in your case) are not compatible. To "fix" your problem quickly, change s.at(i) == " " to s.at(i) == ' ', but your program will remain problematic: it still contains a lot of C code that's problematic in it self, too. A possible C++ version could be this:
#include <iostream>
#include <string>
using namespace std;
int main() {
int count = 0;
string line;
std::getline(cin, line);
for (const auto c: line) {
if (c == ' ') {
count++;
}
}
cout << "Your input \""<< line << "\" contains " << count << " space(s)." << endl;
return 0;
}

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.

Why does the result of an expression depend on where the expression is placed?

I am currently working on a more complex program, and I came across a very weird syntax error best demonstrated with the following minimal example:
#include <iostream>
int main(int argc, char *argv[]){
char c = 1 + '0';
std::cout << 1 + '0' << std::endl;
std::cout << c << std::endl;
std::cout << '0' + 1 << std::endl;
return 1;
}
This example produces the following output:
$ ./program
49
1
49
What appears to be happening here is that when the conversion from a single digit integer expression to a character happens outside a stream statement, it succeeds, but when it happens inside such a statement, it produces a garbage answer.
I tried to find someone else asking something similar on Google, but I can't find anything relevant.
I am using g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609 on Ubuntu 16.04 LTS x64, but the issue occurs in clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final) as well, which rules out a compiler bug.
The result of a int + char is an int. So when you do
char c = 1 + '0';
You actually get
char c = 49;
And now c has the value of 49. When yo go to print that though, cout's operator << is overloaded to take a char and instead of displaying 49 it will display the character that 49 represents.
When you do
std::cout << 1 + '0' << std::endl;
Since 1 + '0' is an int you get the int overload of operator << which just outputs the integer 49.
It should be noted that anything smaller than an int will be promoted to an int when doing arithmetic operations. That means that, char + char, short + short, char + short, ..., will all be an int so even doing something like
std::cout << static_cast<char>(1) + '0' << std::endl;
Will still give you a integer output. You have to cast the result back to a char to get a char like
std::cout << static_cast<char>(1 + '0') << std::endl;
but when it happens inside such a statement, it produces a garbage
answer.
No.
char c = 1 + '0';
std::cout << c << std::endl;
In this case the rvalue int is implicitly converted to char. Then the char overload is used with std::cout, resulting in '1' as ASCII.
std::cout << 1 + '0' << std::endl;
In this case you're printing out the integer right away, so the integer overload is picked, this prints the numeric value of the '1' which is 49.