Boolean logic issue - c++

I was wondering if there was a shorter way to write
if (test != 'e' || test != 'd')
I want to write it like
if (test != ('e' || 'd'))
Or something like this so i don't have to repeat "test !="
Thanks

That's the syntax of the language. There's not much you can do about it... If you don't like the way it looks, you can make a boolean function that contains the tests and then just call that function:
bool isEOrD(char test)
{
return (test != 'e' || test != 'd')
}
...
if (isEOrD(test))
EDIT: There are other ways to write this code (see the comments to this answer), but your original way is probably the cleanest approach.

You could use the old C function strchr:
if (!strchr("de", test))
{
// test is not 'd' or 'e'
}
But I don't know whether it is any nicer to look at… personally I would probably just have the two !=.

C or C++ must evaluate the expressions you write in the syntax of the language. The expression ('e' or 'd') always returns true because the 'or-ing' is done by comparing the bits of the values which will never be the same. How is the compiler to know what you want since in C/C++ a raw character is simply an interpretation of an integer. That's why you can legally write:
char aChar = 'a';
// or
char aChar = 0x41; // hex 41 = ascii 'a'
and have them both work.

Related

While loop going past limit

while (('\0' != *str1) && ('\0' != *str2) &&
(false == sensi) ? (std::toupper(*str1) == std::toupper(*str2)) : (*str1 == *str2)) {
++str1;
++str2;
}
This code keeps looping even past the NULL terminator.
There must be something incredibly obvious I am missing here, but I simply cannot see it.
If either one of those chunks of code between the && gets evaluated as false, it should break, but it does not do so and keeps parsing the string even past the NULL terminator into gibberish.
while (('\0' != *str1) && ('\0' != *str2) &&
(false == sensi) ? (std::toupper(*str1) == std::toupper(*str2)) : (*str1 == *str2))
The ternary operator ?: has lower precedence than nearly all other operators, including the logical AND &&. So, the &&s get applied first, and thus what you are saying here is:
if str1 is not at its NUL terminator, && str2 is not at its own, && we are not comparing case-sensitively,
then ? loop while the strings' current characters are equal case-insensitively,
else : loop while the strings' current characters are equal exactly.
Therefore, you will loop forever if the strings are equal, or at least past their NUL terminators and into Undefined Behaviour Land.
What you instead mean is this, where we wrap the entire ternary expression in parentheses, to override its default precedence and thus make the language evaluate it as the 3rd condition of the &&:
while ( *str1 != '\0' && *str2 != '\0' &&
(!sensi ? std::toupper(*str1) == std::toupper(*str2) : *str1 == *str2) )
i.e. to loop while:
str1 is not at its NUL terminator, &&
str2 is not at its own, &&
( the strings' current characters are equal in ?: the way specified by sensi ).
I would suggest to review operator precedence here, not overuse parentheses where redundant, and not use Yoda conditionals. Also, this large compound condition could perhaps best be expressed as a separate function taking the 2 strs as input and checking each condition separately, to avoid confusing long logical tests.

How to do input validation simply in C++?

I want to give an error message if the input is neither character c nor h but I can't get it to work! I looked up some other answers but they mostly use throw/catch method which I didn't understand at all. I just started programming and error handling is in Chapter 20 or 21. Help me out with the most simple way as possible.
This is what I've tried:
cout << "Enter 'c'(even) or 'h'(odd): ";
cin >> your_guess;
if((your_guess != ('c' || 'h')) == false) {
cout << "Wrong Input. Game is restarting... " << endl;
// restart the game ...
}
But it always says Wrong Input. ....
(your_guess != ('c' || 'h')) == false
is wrong. ('c' || 'h') simply evaluates to true. The built-in operator|| takes two bool arguments:
bool operator||(bool, bool)
And since 'c' and 'h' are both not NUL characters, they convert to true.true OR true is true. The language doesn't create some magical entity with which you can do operator==/operator!= with char to see if the character is among those you've listed.
Then, later the bool and char are promoted to int to do the inequality check. I'd guess your_guess won't be equal to 1. And I don't mean '1' (ASCII 49), but 1 (ASCII 1). So you've effectively written if(true)...
What you meant to say is:
(your_guess != 'c' || your_guess != 'h') == false
or
!(your_guess != 'c' || your_guess != 'h')
or
your_guess == 'c' && your_guess == 'h' // your_guess equal 'c' and 'h' at once?
and now you see that there's something wrong with the logic.
The right code for the condition is one of these:
your_guess != 'c' && your_guess != 'h'
!(your_guess == 'c' || your_guess == 'h')
It's just De Morgan's laws all around.
How to do input validation simply in C++?
If the above is not simple for you, you can use switch (because you're probably going to use it anyway). But each case tests variable against compile-time constant.
If the letters you want to check for are stored in a variable, I suggest this:
std::string valid_characters = "ch"; // this will be our "magical entity"
if(valid_characters.find(your_guess) == std::string::npos)
{
// you have entered a character that is not 'c' nor 'h'
}
You can try
switch(your_guess){
case 'c' :
case 'h' :
// do something
break;
default :
cout<<"invalid Input"<<endl;
break;
}
If you are doing an error message in c++, using cerr instead of cout might be something you may want to think about doing in addition to the changing:
your_guess!=('c'||'h'))==false
To one of the correct forms listed in the other answers

C++ bitwise OR operator

bool OrderUtils::shouldCptyAutoexecute(int Id)
{
bool res =
dummyCache::instance().getVal(Id).getWhitelabelType() == "ABCD";
if (!res)
res |= dummyCache::instance().getVal(Id).getIsPlc() == 1;
return res;
}
The above code checks for 2 Id's and returns true to res if any of the id is present in the database.
Can you suggest a way in which I can compare one more value from the databse table and return true to the value res..Also can you explain what does the second if statement do and the bitwise OR operator?
Sir, just let the short-circuit eval do this for you:
return dummyCache::instance().getVal(Id).getWhitelabelType() == "ABCD" ||
dummyCache::instance().getVal(Id).getIsPlc() == 1;
If the first is true, the second will not fire. Moreover, I assure you a remotely-reasonable optimizing compiler will not re-fire instance().getVal(id) if the returned object has not changed between the getWhitelabelType() and getisPlc() calls. In fact, i would all-but-guarantee it if getWhiteLabelType() is const. (and it certainly looks like it should be).
Regarding the bit work. The expression was pretty-much whacked. though it will work. Unless I read it wrong (and trust me, the list of people that will tell me I am will let me know quickly) it is performing a boolean eval, promoting the resulting true/false bool to an int, promoting the current value of res from bool to int (which is zero, so nothing special there), bitwise-OR-ing that with the expression int, then demoting the final int back to a bool to store in res . I'm surprised this doesn't flag at least a warning on the compiler.
It likely should have been if (!res) res ||= expr, and even then, it is pointless, as you can just use short circuit eval as in the top of this answer to cut out the local res entirely. Consider if res were false. Then the equivalent expression would be res = false || expr. But thats just res = expr. In the !res state it executes in, you may as well just use an assignment.
Finally, regarding adding a third field to your eval, it depends entirely on how you want it added. for an additional logical OR it is pretty simple.
For an expression like (A || B || C) you can just
return dummyCache::instance().getVal(Id).AField() == ATestValue ||
dummyCache::instance().getVal(Id).BField() == BTestValue ||
dummyCache::instance().getVal(Id).CField() == CTestValue;
For more complex operations, some judicious use of parenthesis will go a long way. For example, to return (A || B) && C:
return (dummyCache::instance().getVal(Id).AField() == ATestValue ||
dummyCache::instance().getVal(Id).BField() == BTestValue) &&
dummyCache::instance().getVal(Id).CField() == CTestValue;
Or perhaps (A && C) || (B && !C) (ok this is getting a little overboard...)
return (dummyCache::instance().getVal(Id).CField() == CTestValue)
? (dummyCache::instance().getVal(Id).AField() == ATestValue)
: (dummyCache::instance().getVal(Id).BField() == BTestValue);

Converting char letters to numbers in C++?

I thought I would try and write some encryption program that converts input to numbers in a file.
I made a table, giving each letter its own number. The code itself went a little like this for each letter:
if (Letter = "P")
{
FILEO.open("Encrypted.txt", ios::app);
FILEO << " 259";
FILEO.close();
}
It came up with "cannot convert from 'const char [2]' to 'char'"
Can anyone suggest how I would go about actually getting a number from a letter?
If Letter is a char, use a char literal:
if (Letter == 'P')
...
Your conditional checking is wrong. It should be ==, not =. A single = means assignment whereas a == means conditional checking.
I am assuming Letter is a character array. In that case, you can use strcmp to compare it with P.
if(strcmp(Letter, "P") == 0)
{
// rest of the code
}
Take a look at the strcmp function reference here, if necessary.
If Letter is simply a char, then you need to compare it with P like this -
if(Letter == 'P')
{
// rest of the code
}
A single quote around a character makes it a character literal, which then can be compared against another character using ==.
You can not compare C++ char to C++ string! You should use single quote for chars, not double quotes. Also, the C++ equals operator is not =, it is ==. the single = is the assignment operator.
You should write the condition like this :
if (Letter == 'P')
{
FILEO.open("Encrypted.txt", ios::app);
FILEO << " 259";
FILEO.close();
}
(Letter = "P")
This is an assignment, not comparison.
You probably meant (Letter == "P") which would also be wrong, you need strcmp.
you need to use strcmp to compare....as = is an assignment operator....
I would recommend that when you give us an error message as you did, you give us the full message - including line numbers so that we know where the error occurred (or tell us what line it occurred at). Paying attention to those line numbers can greatly help finding the true problem.
Given the error message I'm assuming Letter is of type char - you need to understand the difference between literal strings (enclosed in double quotes) and literal characters (enclosed in single quotes).
As Luchian also mentioned, you have an assignment rather than an equality test - unlike Visual Basic, if that is where you're coming from, the two have different symbols.
That should thus be:
if (Letter == 'P')

Getting Character Code from char

I have an array of characters populated by cin, but im trying to find a way to check each character individually to make sure its only one of a set number of characters (a-z,A-Z,0-9,[space]).
The easiest way I thought this could be done is to check if the code of the character fell within a certain range. But not sure how to get it.
Alternatively if anyone knows any other ways of doing it, that would be great.
The easiest way is to use isalpha(), isdigit() or isalnum():
char ch = ... // The character
// Original solution
if (isalpha(ch) || isdigit(ch)){
}
// Better solution by fefe (see comments)
if (isalnum(ch)){
}
These are defined in ctype.h: http://www.cplusplus.com/reference/clibrary/cctype/
Otherwise you can also use comparisons:
if ('a' <= ch && ch <= 'z' ||
'A' <= ch && ch <= 'Z' ||
'0' <= ch && ch <= '9'
){
}
This latter approach using comparisons will generalize to arbitrary ranges.
You can easily access a specific character code by using the character you want in single quotes, for example, 'A'. Therefore, if you wanted to check if a character is in a certain range:
char c = //some character
if ( c >= 'A' && c <= 'Z' ) {
//do something
}
should work as you would expect. Additionally, if you are concerned about alpha-numerics specifically, there is a helper function called isalnum, defined in <ctype.h> that checks if a character is an alphanumeric character.
You can determine if the number falls within the range you are looking for within an ASCII table: http://www.asciitable.com/index/asciifull.gif. So >= 48 && < 123.