-3

I am trying to make a little program that will ask the user if they're human and then do a bunch of other stuff afterwards. The following is a snippet of the code where the user is asked whether they're human. Now if you enter anything other than yes or no, the program then loops with the 'goto' statement. The problem that I'm having is that the if statements, when they end go to this 'goto' statement thus looping when the program should end. How can I get the goto statement to be exclusively part of the second else if statement? Failing that, is there another loop structure that I should use? Any help would be greatly appreciated.

#include <iostream>
#include <windows.h>
#include <string>
using namespace std;

int main ()
{
    go:
    string i;

    cout << "Are you Human?>"<<endl;
    cin >> i;

    if (i == "yes"&&"Yes")
        cout<< "Cool"<<endl;

    else if (i == "no"&&"No")
        cout<< "Interesting"<<endl;

    else if (i!= "yes"&&"Yes"&&"no"&&"No")
        cout<< "A simple Yes or No will suffice..."<<endl;
        goto go;

    system("pause");
    return 0;
}
John Smith
  • 87
  • 12
  • This is not a valid case for `goto`. Use a loop construct (such as `while`) instead. – Bartek Banachewicz Jan 28 '14 at 13:18
  • 1
    Also, your conditions look suspect. It looks like you need something of the form `if (i == "yes" || i == "Yes")`. – juanchopanza Jan 28 '14 at 13:19
  • 4
    Here, have a pair of these: `{}` – jrok Jan 28 '14 at 13:20
  • 3
    1) Don't use `goto`, ever. 2) *Always* enable as many compiler warnings as possible, and *listen* to them. 3) *Always* add braces around your code blocks, even if they contain only a single statement. The latter would have partially avoided your problem, because you thought that the indentation of the `goto` would make it depending on the `if` condition (which it isn't). Thanks for making such a brilliant statement in favor of common coding practices. – DevSolar Jan 28 '14 at 13:20
  • Im seeing a lot of downvotes, and then comments on not to use `goto`, but neither explain _why_ not to use it or why it isnt a valid case, ? – Philipp Gayret Jan 28 '14 at 13:23
  • What if they type in YES? – Ferruccio Jan 28 '14 at 13:24
  • @user1066946: Avoiding `goto` doesn't need to be explained in detail anymore. IMHO. – DevSolar Jan 28 '14 at 13:25
  • 1
    @user1066946 DevSolar seems to have a strong opinion on that subject - that certainly is fine if it works for him. Mine is a bit different but the discussions around that subject are e.g.http://stackoverflow.com/questions/24451/is-it-ever-advantageous-to-use-goto-in-a-language-that-supports-loops-and-func/24476#24476 and that one does contain a number of (IMHO) perfectly reasonable uses of `goto`. – Till Jan 28 '14 at 13:29
  • @Till: Opinion born out of 1 1/2 decades of professional work (and pain suffered) in the maintenance coding arena... Your linked question is flagged "language agnostic", this is flagged "C++". In C++, you have language features that invalidate your first two points, and your third point is a "maybe" to begin with, which I would counter with a "measure, optimize, measure". I don't go into more detail as this isn't a discussion forum. – DevSolar Jan 28 '14 at 13:34

4 Answers4

3
  1. You really need to learn how to write if-conditions in C++. For example, you need to change

    if (i == "yes"&&"Yes")
    

    to

    if (i=="yes" || i=="Yes")
    

    to be able to check i is yes or Yes. And change others accordingly.

  2. You need to use braces to define scopes instead of just code indentation (this is just for you, not for compiler). For example,

    else if (... ...)
    {
        cout<< "A simple Yes or No will suffice..."<<endl;
        goto go;
    }
    
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
  • 1
    And some braces might be helpful as well... – Till Jan 28 '14 at 13:21
  • Why would my way not be acceptable? Wouldn't it be shorter and more elegant? – John Smith Jan 28 '14 at 13:24
  • @JohnSmith Except they are not for `C++`. – herohuyongtao Jan 28 '14 at 13:25
  • 1
    @JohnSmith: "Shorter" does not equal "elegant". Most C++ coders consider it "more elegant" if you *always* put those curly braces there, even if it's only a one-line statement following, exactly *because* it's so easy to screw this up. Consider you're looking at someone else's code, without the braces but with the indentation. What was the intention? Did the original coder forget the braces, or add the indentation by accident? Braces make the intention clear. And `goto` is the tactical nuke against any attempt of structured programming. Try drawing a Nassy-Shneiderman diagram of `goto` code... – DevSolar Jan 28 '14 at 13:29
  • @DevSolar Thanks for that explanation, but I was referring to the usage of of this `(i=="yes" || i=="Yes")` compared to this `if (i == "yes"&&"Yes")` – John Smith Jan 28 '14 at 13:37
  • @JohnSmith No need to compare them at all as your style is not valid in C++. – herohuyongtao Jan 28 '14 at 13:39
  • @JohnSmith: Your code does not do what you intended to do. herohuyongtao's code *does* do what you intended to do. Please take the time to figure it out yourself. Check [operator precedence](http://en.cppreference.com/w/cpp/language/operator_precedence), adding parenthesis to your statement, think about what each sub-statement evaluates to, and figure out what your code actually *does* (instead of relying on what you *think* it does, since it does not). – DevSolar Jan 28 '14 at 13:48
  • @herohuyongtao Sorry, I don't mean to be a pain, but here it says that the use of `&&` is valid in C++, so could you explain how I am wrong here. http://www.cplusplus.com/doc/tutorial/operators/ – John Smith Jan 28 '14 at 13:50
  • @JohnSmith it is a 'boolean operator'. That returns TRUE when both arguments are TRUE. What you are saying `If i is equal to "yes" AND if "Yes"` then `do something.` However, I explicitly wrote `AND if "Yes"`. As I said `&&` is a boolean operator. `"Yes"` equals to TRUE because `"Yes"` is NOT equal to `zero/0`. This is perfectly valid as well: `if ("Yes"){}` or `if ('0'){}` ('0' is the ASCII character for 0, which equals integer value 48, 48 != 0 thus `if ('0'){}` is also true. if ('0' && "Yes"){} is also TRUE. Which leads to `if (i == "yes" && '0'){}` to also yield TRUE – Daan Timmer Jan 28 '14 at 14:05
  • @DaanTimmer But does this really matter if it works? – John Smith Jan 28 '14 at 14:27
  • It doesn´t work if you insert "Yes" in your console it will result in False && True which equals in to False. Which will result in you printing the text A simple yes or no would suffice: `"Yes" != "yes"` == TRUE, True && True && True && True == True. – Daan Timmer Jan 28 '14 at 14:33
  • Ah thank you for that explanation. I appreciate your humility and patience. – John Smith Jan 28 '14 at 15:13
1

You have to place the goto statement in the code block of this else-if.

else if (i!= "yes"&&"Yes"&&"no"&&"No")
{
    cout<< "A simple Yes or No will suffice..."<<endl;
    goto go;
}

Also take into account that conditions as

else if (i!= "yes"&&"Yes"&&"no"&&"No")

or

if (i == "yes"&&"Yes")

are invalid, In fact the last condition is equiavelnt to

if ( ( i == "yes" ) && ( "Yes" ) )

as "Yes" is implicitly converted to pointer to its first character then expression "Yes" will be always equal to true and the condition is equivalent to

if ( i == "yes" )

Also it is a very bad idea in general to use goto statement. You should forget that there is goto statement in C/C++. Instead you should use control structures as while or do-while.

For example

#include <iostream>
#include <string>
#include <cstdlib>

using namespace std;

int main ()
{
    string s;

    do
    {
        cout << "Are you Human?>" < <endl;
        cin >> s;

        bool answer;

        if ( answer = ( s == "yes" || s == "Yes" ) )
           cout << "Cool" << endl;

        else if ( answer = ( s == "no" || s == "No" ) )
           cout << "Interesting" << endl;

        else 
           cout << "A simple Yes or No will suffice..." << endl;

    } while ( !answer );      

    system( "pause" );

    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Though in the code I showed variable answer will be assigned in any case it would be better for readability to initialize it to false when it is defined. So maybe it would be better to write bool answer = false; – Vlad from Moscow Jan 28 '14 at 13:50
0

if you want to accept "yes" or "Yes" you should write condition like this:

if (i=="yes" || i=="Yes")

But better solution is make string's letters same case (lower or upper) and then compare it.

αλεχολυτ
  • 4,792
  • 1
  • 35
  • 71
0
int main ()
{
go:
string i;
while(1)
{
    cout << "Are you Human?>"<<endl;
    cin >> i;

    if (i == "yes"|| i == "Yes")
        cout<< "Cool"<<endl;

    else if (i == "no"|| i == "No")
        cout<< "Interesting"<<endl;

    else
    {
        cout<< "A simple Yes or No will suffice..."<<endl;
        break;
    }        
}

system("pause");
return 0;
}

Don't forget that if you don't put curly braces after the statements, only the following statement is to be executed.

Manex
  • 528
  • 4
  • 15