While working on my CS project, I coded the following line:

if(...*stuff* || *morestuff* || *evenMOREstuff* || (strcmp(argv[5], "yes") && strcmp(argv[5], "no"){
cout << "Improper arguments."
exit(1);
}

else{ do more stuff}

Where argv[5] is a program argument supplied by the user. Either a yes or a no should return true; all other values cause the program to exit. The if() statement checks the values of all the program arguments, and if any one exceeds the limits it exits the program.

The reason I'm so confused is why my strcm comparison actually works. I've run it against multiple test cases, and each time it ONLY returns true if it's either yes or no. If anybody could explain my own genius to me it would be appreciated.

strcmp compares the actual values of the character array (string) and the string literal you supply. So you are checking to see if argv has either the value [y][e][s][\n][] or [n][o][\n][][]. If the letters are capitalized, then the binary values for the letters are not the same, meaning that the strings are really not equal (n != N).

strcmp doesn't return true or false, it returns a comparison:

<0 - The first string is "smaller" than the second string
>0 - The first string is "greater than the second string
0 - The strings are "equal"

In your test strcmp(argv[5], "yes") && strcmp(argv[5], "no") , you're saying evaluate to true if argv[5] is not equal to "yes" and also not equal to "no". This is because the result of strcmp is being used in a boolean context, where 0 is false and non-zero is true. A more complete example is:

( strcmp ( argv[5], "yes" ) != 0 ) == true 
&& ( strcmp ( argv[5], "no" ) != 0 ) == true

You can apply a truth table to this to figure out exactly why it works in all cases:

LT: argv[5] == "yes"
LF: argv[5] != "yes"
RT: argv[5] == "no"
RF: argv[5] != "no"

   | RT | RF
LT | ~  | F
LF | F  | T

~: Impossible result

Of course, it couldn't hurt to explain why you think it shouldn't work. I assume that's why you asked the question in the first place, because people tend not to be confused that something works when they expect it to work. ;)

strcmp doesn't return true or false, it returns a comparison:

<0 - The first string is "smaller" than the second string
>0 - The first string is "greater than the second string
0 - The strings are "equal"

In your test strcmp(argv[5], "yes") && strcmp(argv[5], "no") , you're saying evaluate to true if argv[5] is not equal to "yes" and also not equal to "no". This is because the result of strcmp is being used in a boolean context, where 0 is false and non-zero is true.

So how does the fact that it equals yes or no change the result of the comparison? If I input "yes", strcmp(argv[5], "yes") returns a 0, but what about the strcmp(argv[5], "no")? Since it's an X&Y, it only returns false if both X&Y are true. But either X is true or Y is true, they can't both be true, so why does ~(XvY) cause an error? All I know is the result of the comparison has to be false, since it's working when it's ~(XvY)

>If I input "yes", strcmp(argv[5], "yes") returns a 0, but what about the strcmp(argv[5], "no")?
It doesn't run because the logical operators are short circuited. In the case of &&, both sides have to be true for the whole expression to be true, but if the left side is false, there's no point in testing the right side because the result is already known to be false. But the result would be the same even if the right side were evaluated because, of course, the left side resulted in false.

>But either X is true or Y is true, they can't both be true
It seems like you're getting turned around by the negation. "True", in this case, is when argv[5] is not equal to the second argument. It's certainly possible that both can be true because argv[5] could be neither "yes" nor "no". The impossible case is when both sides are false, because argv[5] can't be both "yes" and "no" at the same time.

This article has been dead for over six months. Start a new discussion instead.