Are there ways to do if statements inside a cout line? - c++

I'm starting to learn C++, and something useful from my main language Lua, is the ability to say:
print(true/false and 1 or 0)
1 or 0 being anything but it seems in c++ it doesnt work the same way?
What I tried for C++ was
cout << (score == 0) and "Valid";
But only a true if check seems to work
if (score == 0) {
cout << "Valid";
} else {
cout << "A";
}

std::cout << ((score == 0) ? "Valid" : "A");

The << in your code isn't simply a syntax, it's an operator:
std::basic_ostream<CharT,Traits>::operator<<
Your attempt will not produce any compilation errors (assuming you have using namespace std;):
cout << (score == 0) and "Valid";
// ^^ T/F ^^ ^^ T ^^
Apply some boolean algebra and that's equivalent to:
cout << true; // if score is 0
cout << false; // if score is not 0
That's certainly not what you are trying to acheive.
Are there ways to do if statements inside a cout line?
if (score == 0)
cout << "Valid";
else
cout << "A";
You can do that using the conditional operator ?:
cout << (score == 0 ? "Valid" : "A");
But this approach is not guaranteed to work always. For example:
cout << (condition ? "String" : 1234);
Reason: Why in conditional operator (?:), second and third operands must have the same type?
Rearranging it like this will work:
condition ? cout << "String" : cout << 1234;
Now, talking about your Lua style:
print(true/false and 1 or 0)
I don't know Lua but that looks like a function. If you are looking for some template like that, try this:
template <typename T, typename U>
void conditionalPrint(const bool& condition, const T& arg1, const U& arg2)
{
condition ? cout << arg1 : cout << arg2;
}
You can use it like this:
conditionalPrint(score == 0, "Valid", "A");
conditionalPrint(someCondition, "String", 1234);
Of course, I'm not going to explain how that works because you're new to C++. I would still recommend the if-else way of doing it. Readability of your code is very important:
if (condition)
{
cout << "true block";
}
else
{
cout << "false block";
}
"Lot can be learned by comparing two lanugages and try to see if what can be done in one can also be done in the other, but usually what is idiomatic in one can be crap in the other. Anyhow, I had my fun with exploring the issue, but imho the conclusion is as important as the rest of the answer" - idclev

Related

Does cout treat bool as integer or integer as bool?

Why does this program
int a = 8;
cout << a && true ;
cout << typeid(a && true).name();
output
8bool
Frankly, I expected "truebool" or "8int".
Is operator << of cout object involved in this or is it a precedence issue?
Does it convert true to 1 as in the case when we cout << true;?
typeid(a && true) gives us bool, though the cout << a && true; is obviously a number?
Indeed it is an operator precedence issue. << has a higher precedence than &&.
One shorthand trick you can use to interpret an integer value to bool is to double-NOT it:
cout << !!a;
This is a matter of style, which may be divisive within the C++ community. So, if you don't want to be controversial, then the following may be more acceptable:
cout << (a ? true : false);
cout << static_cast<bool>(a);
cout << (a != 0);
Personally, I think that (a && true) is somewhat ugly. But I'm sure there are some who would argue otherwise.
In the end, the compiler should be generating the same result no matter how you write it.

Can I compare with more than one string in an if statement?

This is gonna be laughed at because I'm probably very stupid, but can I use more than one string as a condition in an if statement?
#pragma once
#include <iostream>
#include <string>
#include "Baxter.h"
#include "Inventory.h"
#include "Room1Items.h"
int woman = 6;
int children = 5;
int inputNumberOfAnimalsToSave;
int numberOfAnimals;
int numberOfAnimalsToKill;
int numberOfAnimalToTakeHome;
std::string Yes;
std::string firstAction;
bool killRemainingAnimals;
int playerSaidYes;
int AddNumber()
{
numberOfAnimals = woman + children;
return numberOfAnimals;
}
int RemoveNumber()
{
numberOfAnimalsToKill = numberOfAnimalToTakeHome - numberOfAnimals;
return numberOfAnimalsToKill;
}
int InputNumber()
{
std::cout << " Comrade Kurchenko: Well, they are irridiated and will most likely end up poisioning \n";
std::cout << " your family, but sure, why not! How many animals Shall we Save ?\n ";
std::cin >> inputNumberOfAnimalsToSave;
numberOfAnimalToTakeHome = numberOfAnimals - inputNumberOfAnimalsToSave;
return numberOfAnimalToTakeHome;
}
int DoYouWantToKillTheRest()
{
std::cout << " Comrade Kurchenko: Fair Enough Comrade! Do you want to move on? \n\n";
std::cout << " Private Lenin: "; std::cin >> Yes;
while (Yes == "No")
{
//std::cout << " Comrade Kurchenko: So, you want the remaining " << numberOfAnimalToTakeHome << " Put The sleep do you?\n\n";
//std::cout << " Private Lenin: Im afraid so sir!\n\n";
//std::cout << " Comrade Kurchenko: Then so be it. They will be better off dead by our hands, than starving to death.\n\n\n\n";
//std::cout << " *** Loud Bangs and Then Silence....\n\n\n ***";
std::cout << " Comrade Kurchenko: What do you want to do?\n";
std::cout << " Private Lenin: "; std::cin >> firstAction; std::cout << "\n";
while (firstAction != "MoveOn")
{
if (firstAction == "Take food" || "Recover Meal" )
{
if (canTakeFood)
{
TakeFood();
std::cout << " You have taken a peice of food \n";
DoYouWantToKillTheRest();
}
if (canTakeFood == false)
{
std::cout << " There is no more food to take \n";
DoYouWantToKillTheRest();
}
}
if (firstAction == "Eatfood")
{
EatFood();
DoYouWantToKillTheRest();
}
if (firstAction == "Inventory")
{
ShowInventory();
DoYouWantToKillTheRest();
}
if (firstAction == "Ouch")
{
JabAFingerInYourEye();
std::cout << " Comrade Kurchenko : Why the hell did you stab yourself in the eye?\n\n";
std::cout << " Private Lenin : I dont know sir, its like someone was controlling my arm!\n";
DoYouWantToKillTheRest();
}
if (firstAction == "Look")
{
Look();
DoYouWantToKillTheRest();
}
if( firstAction == "Help")
{
WhatCanIDo();
DoYouWantToKillTheRest();
}
if (firstAction == "Baxter")
{
ShowBaxter();
std::cout << "Here is baxter";
DoYouWantToKillTheRest();
}
}
return 0;
}
return 0;
}
I've tried it and get no bugs when I run it. It just doesn't work.
I have tried to google it but I can't seem to find the right way to word it to get results. Messing around with a console based text adventure.
I've googled as many different ways of asking this question and can't get any results that help me.
I get no error messages. It runs fine, it just doesn't work.
"Can I compare with more than one string in an if statement?" - Sure you can (I'm assuming we are talking about std::strings here).
You are doing
if (firstAction == "Take food")
If you wanted to test against two strings you could do:
if (firstAction == "Take food" or firstAction == "Drop food")
You could change that or to || which is more conventional, but both are valid and do the same thing.
In C++ (and most other programming languages) you usually can't compare one thing (a string variable) to multiple others in one operation because of the way operator precedence is defined:
// Does not work!!
if (firstAction == "Take food" || "Recover Meal" )
// Because it will evaluate to (firstAction == "Take food") || "Recover Meal"
Rather you use logical operators to combine the result of one comparison with another comparison:
if (firstAction == "Take food" || firstAction == "Recover Meal")
{
You should read up on logical operators in C++ to learn more, for instance here: https://www.learncpp.com/cpp-tutorial/36-logical-operators/
If you want to dynamically compare to a whole list of strings, then you can do so of course as well:
std::set<std::string> validActions = {"Take food", "Recover meal"};
if (validActions.find(firstAction) != validActions.end())
{
// ... found a valid action ...
This is not how you compare c-strings in C++. That type of string is just an array of characters and operator == tells if it is the same array, not if it has the same content.
To compare strings properly use function strcmp from <cstring>.
firstAction == "Take food"; // bad
strcmp(firstAction, "Take food") == 0; // good
Better yet solution would be using class std::string which allows to use normal operators.
std::string(firstAction) == "Take food"; // good
std::string(firstAction) == std::string("Take food"); // also good
firstAction == std::string("Take food"); // also good
Or, like #JVApen has hinted, maybe even better solution would be to use std::string_view.
firstAction == std::string_view("Take food"); // good
firstAction == "Take food"sv; // the same meaning as above but written shorter
You just need to remember to insert line using std::operator""sv; before that. (using namespace std; would also do.)
If you comparing string properly (let's say using the std::string_view) then of course you can use || (or) or && (and) or any other operator to make multiple comparisons in a single if.
if (firstAction == "Take food"sv || firstAction == "Take water"sv)
{
// do stuff
}
if (firstAction == "Take food"sv && !canTakeFood)
std::cout << " There is no more food to take \n";
LoopAndDoAction();
}
(This code probably doesn't make sense but it's just an example.)
Depending on what are you trying to do, consider using enum instead of string constants. Enums are faster, more readable, take less memory and there is harder to make mistake like a type when using it. Actually, only situation I can think of when you would not want to use enum would be parsing user input.
The second if is with who you can compare strings a lot of strings if you find some condition true on these if, the entire condition will be true.
I exaplained all on code //comments
Documentation: http://www.cplusplus.com/reference/string/string/compare/
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1ok = "Im a string";
string str2ok = "Im a string";
string str3ok = "Im a string different";
//First condition with and operator (&&) you can compare with a lot && operators
if(str1ok.compare(str2ok) == 0 && str3ok.compare(str2ok) == 0){ //First condition is true, second false, this condition is false because have true and false, need have true and true for be true
cout << "1st condition" << endl;
}
//Another condition with or operator (||) one condition need be true, if not is false
if(str1ok.compare(str2ok) == 0 || str3ok.compare(str2ok) == 0){ //First condition is true, only for this this condition is true, second condition is false.
cout << "2nd condition" << endl;
}
//You can make a mixed the operators like this some condition && (anothercondition || condition)
return 0;
}
Ouptput: https://onlinegdb.com/By39WpOGS

Using multiple conditions in an if statement in C++

I am trying to create a complex if statement in C++ that will save me from writing a whole bunch of if statements, I am wondering if this code below actually makes sense or I am overlooking an error.
if(input==choice) {
cout << "Tie!" << endl;
}else if(input=="rock" && choice=="scissors"
|| input=="scissors" && choice=="paper"
|| input="paper" && choice=="rock") {
cout << input " beats " << choice << ", you win!" << endl;
}else if(input=="rock" && choice=="paper"
|| input=="scissors" && choice=="rock"
|| input=="paper" && choice=="scissors"){
cout << choice << " beats " << input << ", you lose!" << endl;
}
What I am trying to achieve is:
"if input is x AND choice is y, OR if...."
Basically I'm testing multiple "if-and" conditions so that a single line of code will execute if it hits any of the if-and conditions. The output throws a "no match for 'operator||'" error.
You have a typo in input="paper" && choice=="rock"), but instead of fixing the typo I would suggest you to fix the code. No wonder you made a typo in this giant block of conditions. You have lots of repetion and mixing logic with output. If you spend some lines on includes, you can save some on code...
#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
bool win(const std::string& input, const std::string& choice) {
static const std::vector<std::pair<std::string, std::string>> wins =
{ { "rock", "scissors" },
{ "scissors", "paper" },
{ "paper", "rock" }
};
return std::find(wins.begin(), wins.end(), std::make_pair(input, choice))
!= wins.end();
}
int main() {
std::string choice = "paper";
std::string input = "scissors";
if (win(choice, input)) { std::cout << "you win! \n"; }
else { std::cout << "you lose! \n"; }
}
As next step you should eliminate all that strings, eg by using enums as discussed in the comments.

Cout String and int in ternary operator

A line in my c++ code reads:
cout<<(i%3==0 ? "Hello\n" : i) ;//where `i` is an integer.
But I get this error:
operands to ?: have different types 'const char*' and 'int
How can I modify the code (with minimum characters)?
Ugly:
i%3==0 ? cout<< "Hello\n" : cout<<i;
Nice:
if ( i%3 == 0 )
cout << "Hello\n";
else
cout << i;
Your version doesn't work because the result types of the expressions on each side of : need to be compatible.
You can't use the conditional operator if the two alternatives have incompatible types. The clearest thing is to use if:
if (i%3 == 0)
cout << "Hello\n";
else
cout << i;
although in this case you could convert the number to a string:
cout << (i%3 == 0 ? "Hello\n" : std::to_string(i));
In general, you should try to maximise clarity rather than minimise characters; you'll thank yourself when you have to read the code in the future.
operator<< is overloaded, and the two execution paths don't use the same overload. Therefore, you can't have << outside the conditional.
What you want is
if (i%3 == 0) cout << "Hello\n"; else cout << i;
This can be made a bit shorter by reversing the condition:
if (i%3) cout << i; else cout << "Hello\n";
And a few more characters saved by using the ternary:
(i%3)?(cout<<i):(cout<<"Hello\n");
std::cout << i % 3 == 0 ? "Hello" : std::to_string(i);
But, as all the other answers have said, you probably shouldn't do this, because it quickly turns into spaghetti code.

Optimized way to check the value of a variable with enum members value

Hello I have the code below:
enum {a, b, c, d, ..., z} abc;
int main()
{
int val = 20;
if (val == a || val == b ||val == c||val == d..... || val == z)
{
/*Do something*/
}
}
Is there any other way so that we can skip the OR operation because if there are 1000s of enum members then how can we do ahead with checking with all members.
Please help.
A modern compiler should just be able to optimize such code if, as in your case, the value of the expression is known at compile time. For readability and error checking I think that using a switch would be better:
switch (val) {
case a:;
case b:;
....
// your code goes here
}
As said, performance wise there shouldn't be much difference, the compiler will transform this to a table lookup (or other clever things) if appropriate or completely optimize it out if val is known at compile time.
But you can have the advantage of error checking compilers, here. If you don't have a default case, most compilers will warn you if you omit one of the enumeration constants. Also I think that this is clearer, since it doesn't repeat the evaluation of val all over the place.
other(faster) solution will be the following
bool isInenum (int val)
{
bool retVal = false
switch(val)
{
case a:
case b:
case c:
case d:
{
retVal = true;
}
}
return retVal;
}
Since enumerator values are assigned sequentially, putting an if statement like this would be enough:
if(val<=z)
You could use a map in C++. With a map you can write a compact test without the numerous == and ||.
But you first need to initialize a map and I'm not sure if you can do this initialization in a compact way for an arbitrary enum.
#include <iostream>
#include <map>
using namespace std;
enum abc { a = 1, b = -1, c = 3, d = 0 };
int main()
{
map<int, int> m;
m[a] = m[b] = m[c] = m[d] = 1;
cout << "b is " << ((m.find(b) == m.end()) ? "NOT " : "") << "in m" << endl;
cout << "3 is " << ((m.find(3) == m.end()) ? "NOT " : "") << "in m" << endl;
cout << "10 is " << ((m.find(10) == m.end()) ? "NOT " : "") << "in m" << endl;
return 0;
}
Output (ideone):
b is in m
3 is in m
10 is NOT in m