Skip to main content
GameDev.net gamedev.net
🔒 Locked

(C++ Beginner) I hate to post here, but... why won't my "if" statement evaluate a string?

Started by BrandonSnider Jul 15, 2012 at 2:46 PM 34 replies 8.9k views
Original Post
BrandonSnider
BrandonSnider
I've worked with other languages in the past including basic and a lot of scripting languages, and I have worked a decent bit on C++ too. I haven't worked on C++ in quite a while now, and last night I was trying to refresh myself on the basics... so--and this is a little embarrassing--I wrote this small piece of code for a console program to send my girlfriend:


#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//Vars
string username = "";

//Execute
cout << "Hello \n";
cin.get();
cout << "What is your name? ";
getline (cin, username);
cout << "Your name is: " << username;
cin.get();
if (username == "Tiffany" || "tiffany" || "Tiffany McClure" || "tiffany McClure" || "Tiffany Mcclure" || "tiffany mcclue")
{
cout << "Your name is Tiffany... \n The Creator has a message for you: \n I love you Cupcake";
cin.get();
}
else
{
cout << "Your name is not Tiffany.";
cin.get();
}
return 0;
}


The problem is... it doesn't appear that the "if (username == "Tiffany" || "tiffany" || "Tiffany McClure" || "tiffany McClure" || "Tiffany Mcclure" || "tiffany mcclue")" statement evaluates correctly, as the program always displays the cout message in the "if" block, even if the if statement should be false.


I know these are beginner C++ concepts that have nothing to do with game development, but... this is like the only forum acct. I have for anything like this, and I hate to create another just to ask this somewhat stupid question.

I appreciate any help with this, I'm trying to pick up C++ again so that maybe I can do something useful with it.


EDIT: Oops. I haven't been on this site in a while. Forgot there was a "For Beginners" Section. This probably belongs there. Sorry about that.
zacaj
zacaj
You need to do
if (username == "Tiffany" || username =="tiffany"
BrandonSnider
BrandonSnider
Thanks... XD I knew I would feel dumb at the end of this one... always the little things.

Appreciate it. Sometimes it's just helpful to have someone else look at it.
mind in a box
mind in a box
I don't know how std::string handles this, but you should be able to do [font=courier new,courier,monospace]if(stricmp(username.c_str(), "Tiffany McClure")==0) [/font]to do a case insensitive comparison.
(stricmp measures some kind of "difference" between the strings, so you have to check for == 0)
Servant of the Lord
Servant of the Lord
I usually convert my strings to all lowercase or uppercase, if I'm going to compare them to multiple possibilities.


std::string name = "Person McPerson";
std::transform(name.begin(), name.end(), name.begin(), ::tolower);

if(name == "person mcperson")
{
//...
}


tolower(), std::transform
Alex Melbourne
Alex Melbourne
[...] convert [...] strings to all lowercase...


I was going to suggest this. This is a great technique. Saves space and it means you catch strange possibilities like "TiffAnY MCClurE"; which would otherwise take up huge amounts of space if you tried to catch every single version.
Krohm
Krohm

Saves space
How?
Previously "Krohm"
Aardvajk
Aardvajk

[quote name='BinaryPhysics' timestamp='1342395942' post='4959383']
Saves space
How?
[/quote]


Stops the exe having to have all the different supported permutations of the string stored in its data section.

"Saves space" is pushing it though, overhead of calling method is likely to outweight space saving but of course this is irrelevant and space saving is hardly the reason to use this approach.
Krohm
Krohm
I seriously hope you're jocking.
Using this to not store the permutations is not saving space.
Rather, doing the permutation thing is brain damaged. And don't even get me started on checking the match. I'm sure I've seen it on the daily WTF.
Thus, not storing them is not about saving space but rather doing things right.
Previously "Krohm"
mark ds
mark ds

Using this to not store the permutations is not saving space.


Actually, it saves a quarter of a meg ;-)

Which is eight times as much memory as my first computer had!
Servant of the Lord
Servant of the Lord

I seriously hope you're jocking.
Using this to not store the permutations is not saving space.
Rather, doing the permutation thing is brain damaged. And don't even get me started on checking the match. I'm sure I've seen it on the daily WTF.
Thus, not storing them is not about saving space but rather doing things right.

I'm confused about what you are disagreeing with.

Are you saying that this...

if(name == "person mcperson" || name == "Person Mcperson" || name == "Person McPerson"
|| name == "PERSON MCPERSON" || name == "person MCPERSON" || name == "PERSON mcperson" || ...etc... )
{
//...
}


...is better than this:
std::string name = "Person McPerson";
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
if(name == "person mcperson")
{
//...
}


Or are you just saying to cache the lowercase name when possible, so you don't have to convert it every function call?

As for 'saving space', I fully agree that any 'space' you save is absurdly small and unimportant if developing for a modern PC. For me, the benefit of the second one is about writing cleaner and easier-to-maintain code, and also ensuring you catch all the valid possibilities and not just some of them.


Actually, it saves a quarter of a meg ;-)
Which is eight times as much memory as my first computer had!

How does it save a quarter of a megabyte? Worst case scenario, with the example I gave ("Person McPerson"), it'd save 32 kilabytes I think - and only if someone bothered to type out every possible lowercase vs uppercase version of "Person McPerson", starting with "person mcperson", "Person mcperson", "PErson mcperson", "PERson mcperson", and so on, which is unlikely.
mark ds
mark ds
2^14 permutations * 16 bytes (assuming ascii, 14 characters + a space + a null) = 256kb!
kunos
kunos


if (username == "Tiffany" || "tiffany" || "Tiffany McClure" || "tiffany McClure" || "Tiffany Mcclure" || "tiffany mcclue")





Am I the only one thinking that looks pretty elegant? Is there any language that implements this way of checking the same variable for different boolean cases?

It looks to me like "Tiffany" is the real string to look for here, so I would convert to lowercase and check for "tiffany".. what if she wrotes "Tiffany Cupcake" ? You'll miss that.
King Mir
King Mir

[quote name='bls61793' timestamp='1342363560' post='4959267']

if (username == "Tiffany" || "tiffany" || "Tiffany McClure" || "tiffany McClure" || "Tiffany Mcclure" || "tiffany mcclue")





Am I the only one thinking that looks pretty elegant? Is there any language that implements this way of checking the same variable for different boolean cases?

It looks to me like "Tiffany" is the real string to look for here, so I would convert to lowercase and check for "tiffany".. what if she wrotes "Tiffany Cupcake" ? tongue.png You'll miss that.
[/quote]Some languages allow this:
switch(name){
case "Tiffany":
case "tiffany":
case "Tiffany McClure":
...
break;
default:
...
}
Close enough?
Servant of the Lord
Servant of the Lord

Some languages allow this:
switch(name){
case "Tiffany":
case "tiffany":
case "Tiffany McClure":
...
break;
default:
...
}
Close enough?

C++ switch statements only work with some data types (mostly ints) - not with std::strings. Even so, that's pretty ugly syntax. happy.png
Cornstalks
Cornstalks
Am I the only one who noticed the typo ([font=courier new,courier,monospace]... "tiffany McClure" || "Tiffany Mcclure" || "tiffany mcclue"[/font])? One big reason checking each permutation sucks is because it's too easy to introduce human error.

I'd say convert to lower (or upper) case and check the string. I love regular expressions, but I probably wouldn't use them here.
King Mir
King Mir

[quote name='King Mir' timestamp='1342470870' post='4959728']
Some languages allow this:
switch(name){
case "Tiffany":
case "tiffany":
case "Tiffany McClure":
...
break;
default:
...
}
Close enough?

C++ switch statements only work with some data types (mostly ints) - not with std::strings. Even so, that's pretty ugly syntax. happy.png
[/quote]Which is why I said "some languages" and not "c++ and some languages". Why do you think switches are ugly?
Servant of the Lord
Servant of the Lord

[quote name='Servant of the Lord' timestamp='1342471896' post='4959736']
C++ switch statements only work with some data types (mostly ints) - not with std::strings. Even so, that's pretty ugly syntax. happy.png
Which is why I said "some languages" and not "c++ and some languages"[/quote]Ah, I thought your "some languages" was a not-so-subtle "hint hint", referring to C++ itself (What with the topic being about C++, and the "Close enough?" comment).

Why do you think switches are ugly?[/quote]
Not switches, per se, but using switches (which are typically meant to branch logic) to imitate the use of AND logic (which is what && is for).
In some situations it may be the best solution, but in general I prefer to use if() when I mean logical IF, and && when I mean logical AND. smile.png

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.