Thread: Option to "Continue or Quit" will not work.

  1. #1
    Registered User
    Join Date
    Nov 2012
    Posts
    11

    Option to "Continue or Quit" will not work.

    Hello,

    My father and I are learning C with the intention of eventually learning C++.

    This program worked fine until I tried to add a "Continue or Quit" option. I've spent at least 6 hours trying to make it work.

    Will someone please tell me what I need to do in order to make it work.

    Been learning C for only about 3 weeks.

    Thank you

    Code:
    #include <stdio.h>
    
    int best_team(void);
    int main(void)
    {
    int team;
    int again = 0;
    team = best_team();
    
         printf("\nYour favorite team on this list is the %s\n\n",team);
    
    
    
         /*THIS IS THE PART THAT IS NOT WORKING
    
         /*printf("Would you like to choose another team?\n\n");
         printf("Enter 1 to choose another team or 0 to quit.\n\n");
         scanf("%d", again);
    
         if(again == 1);
         {
         return main();
         }
         */
    
    
    
         system("PAUSE");
         return 0;
    
    }
    int best_team(void)
    {
    int choice = 0;
    
    do
    {
    printf("\n");
    printf("\nWho is your favorite team on this list?\n");
    printf("\n1 - Seattle Seahawks?");
    printf("\n2 - San Francisco 49'ers?");
    printf("\n3 - Arizona Cardinals?");
    printf("\n4 - St. Louis Rams?");
    printf("\n");
    printf("\nPlease make your selection and press ENTER\n\n");
    
    scanf("%d", &choice);
    
    if(choice < 1 || choice > 4)
    
              printf("\nIm sorry, that selection is not valid; you must choose 1,2,3 or 4.\n");
    if(choice < 1 || choice > 4)
              printf("\nPlease make a valid selection\n\n");
    }
    while( choice < 1 || choice > 4 );
    
    
    if(choice == 1)
    
              return "Seattle Seahawks.\nEXCELLENT CHOICE.\nThey are the best team in the land.";
    
    if(choice == 2)
    
              return "San Francisco 49'ers.\nThey are a fine team...\nbut not as good as our Seahawks.";
    
    if(choice == 3)
    
              return "Arizona Cardinals.\nA decent team over-all...\nbut not the best team in the land.";
    
    if(choice == 4)
    
              return "St. Louis Rams.\nPerhaps you should choose again...";
    
    
    }

  2. #2
    Registered User camel-man's Avatar
    Join Date
    Jan 2011
    Location
    Under the moon
    Posts
    693
    Code:
    scanf("%d", again);
    You are missing the '&' before the variable 'again'. That was what was probably causing your crash.

    Also
    Code:
    printf("\nYour favorite team on this list is the %s\n\n",team);
    team is an integer, when you want to display an integer you need to use either %i or %d. You have %s which is to display strings in C

    Code:
    if(again == 1);
         {
         return main(); // You need to return an integer perhaps 0 for success, strictly up to you.
         }
    Last edited by camel-man; 11-09-2012 at 01:09 AM.

  3. #3
    Registered User
    Join Date
    Nov 2012
    Posts
    11
    Quote Originally Posted by camel-man View Post
    Code:
    scanf("%d", again);
    You are missing the '&' before the variable 'again'. That was what was probably causing your crash.

    Also
    Code:
    printf("\nYour favorite team on this list is the %s\n\n",team);
    team is an integer, when you want to display an integer you need to use either %i or %d. You have %s which is to display strings in C

    Code:
    if(again == 1);
         {
         return main(); // You need to return an integer perhaps 0 for success, strictly up to you.
         }
    I should have seen that the & was missing.

    Now there is another problem.

    When I enter "0" to quit, it continues rather than quitting.

    Any idea as to why it will not quit?

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by steveryan View Post
    My father and I are learning C with the intention of eventually learning C++.
    Cool! I will say, C and C++ are two different languages. They overlap but C is certainly not a prerequisite for C++. Learning C first may help you a bit in C++, but you would probably be much better off just learning C++ directly. Thankfully, if you decide to switch to C++, you only spent a few weeks on C, and what you already learned should transfer over pretty well.

    camel-man is right, in that you need to use %i or %d to print an integer (not %s). It seems, however, that you want best_team to return a string, so you should change the prototype and definition to something like the following:
    Code:
    char *best_team(void)
    Make sure you are using char * to store the result of best_team().
    Code:
    char *team;
    team = best_team();
    printf("\nYour favorite team on this list is the %s\n\n",team);
    Since team is now a string, you want to keep the %s in your printf.

    On to your problem:
    Code:
    /*THIS IS THE PART THAT IS NOT WORKING
    
    /*printf("Would you like to choose another team?\n\n");
    printf("Enter 1 to choose another team or 0 to quit.\n\n");
    scanf("%d", again);
    
    if(again == 1);
    {
    return main();
    }
    There are a couple problems with this code:

    1. You have a semicolon after your if statement, which means the body of the if (what the code does when the condition is true) is empty. Then, everything after it executes regardless.
    2. You are recursively* calling main, and try to return the result of that. Recursively calling main is never the right way to handle repeating a program.


    Use a do-while loop, similar to the one you used to read the favorite team. Here's some pseudo-code to help you along:
    Code:
    do {
        team = best_team();
        print "your favorite team..."
        print "enter 1 to play again"
        read choice into 'again' variable
    } while (again == 1);  // if they enter 1, play again, otherwise, quit
    One other thing I noticed:
    Code:
    if(choice < 1 || choice > 4)
              printf("\nIm sorry, that selection is not valid; you must choose 1,2,3 or 4.\n");
    if(choice < 1 || choice > 4)
              printf("\nPlease make a valid selection\n\n");
    You can enclose multiple statements in a single if statement, just use curly brackets like you do to enclose a function or loop:
    Code:
    if(choice < 1 || choice > 4) {
              printf("\nIm sorry, that selection is not valid; you must choose 1,2,3 or 4.\n");
              printf("\nPlease make a valid selection\n\n");
    }
    I'm off to bed, but that should give you something to chew on for a while.

    * Recursion is when a function calls itself. This is often okay, and sometimes it's the best solution to a problem, just not this time.

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    11
    Thank you all very much for your help!!!

    I do keep getting this "warning: return makes integer from pointer without a cast"

    I suspect this is because I am returning a string to an int.

    However, the program compiles showing 0 errors and runs as I intended.

    Here is the working program:

    Code:
    #include <stdio.h>
    
    int best_team(void);
    int main(void)
    {
    int team;
    int again = 0;
    team = best_team();
    
         printf("\nYour favorite team on this list is the %s\n\n",team);
         printf("Would you like to choose another team?\n\n");
         printf("Enter 1 to choose another team or 0 to quit.\n\n");
         scanf("%d", &again);
    
         if(again == 1)
         {
         return main();
         }
    
         system("PAUSE");
         return 0;
    
    }
    int best_team(void)
    {
    int choice = 0;
    
    do
    {
    printf("\n");
    printf("\nWho is your favorite team on this list?\n");
    printf("\n1 - Seattle Seahawks?");
    printf("\n2 - San Francisco 49'ers?");
    printf("\n3 - Arizona Cardinals?");
    printf("\n4 - St. Louis Rams?");
    printf("\n");
    printf("\nPlease make your selection and press ENTER\n\n");
    
    scanf("%d", &choice);
    
    if(choice < 1 || choice > 4)
              printf("\nIm sorry, that selection is not valid; you must choose 1,2,3 or 4.\n");
              printf("\nPlease make a valid selection\n\n");
    }
    while( choice < 1 || choice > 4 );
    
    
    if(choice == 1)
    
              return "Seattle Seahawks.\nEXCELLENT CHOICE.\nThey are the best team in the land.";
    
    if(choice == 2)
    
              return "San Francisco 49'ers.\nThey are a fine team...\nbut not as good as our Seahawks.";
    
    if(choice == 3)
    
              return "Arizona Cardinals.\nA decent team over-all...\nbut not the best team in the land.";
    
    if(choice == 4)
    
              return "St. Louis Rams.\nPerhaps you should choose again...";
    
    
    }

  6. #6
    Registered User camel-man's Avatar
    Join Date
    Jan 2011
    Location
    Under the moon
    Posts
    693
    Yes you are right about that warning. Take a look at what Anduril has suggested about the way you are recursively calling main on line 17. As well as the char * return type that should be instead of int in your function best_team return type. The correct way to call that function should be

    Code:
    char* best_team(void);
    char* team;

  7. #7
    Registered User
    Join Date
    Nov 2012
    Posts
    11
    Quote Originally Posted by camel-man View Post
    Yes you are right about that warning. Take a look at what Anduril has suggested about the way you are recursively calling main on line 17. As well as the char * return type that should be instead of int in your function best_team return type. The correct way to call that function should be

    Code:
    char* best_team(void);
    char* team;
    I was able to make these changes and get the warning to go away. I had to put the char* in 3 places (function prototype definition, the variable declaration, and where the function is executed).

    I also put some data-checking stuff (a "do...while") where the "continue or quit" option is given so if the user enters anything besides a "1" or a "0" it will inform the user of the error and give the opportunity to start over.

    Instead of recursively calling the main, I am instead calling "return 0" and put the "system("PAUSE")" at the end of the main.

    I really like the way it is working now

    Code:
    #include <stdio.h>
    
    char* best_team(void);
    int main(void)
    {
    char* team;
    int again = 0;
    team = best_team();
    
         printf("\nYour favorite team on this list is the %s\n\n",team);
         printf("Would you like to choose another team?\n\n");
    do
    {
         printf("Enter 1 to choose another team or 0 to quit.\n\n");
         scanf("%d", &again);
    
         if(again < 0 || again >1)
              {
              printf("\nIm sorry, that selection is not valid; you must enter 1 or 0.\n");
              printf("\nPlease enter a valid selection\n\n");
              }
    }
         while(again < 0 || again >1);
         if(again == 0)
                  {
                  return 0;
                  }
         return main();
         system("PAUSE");
    }
    char* best_team(void)
    {
    int choice = 0;
    
    do
    {
    printf("\n");
    printf("\nWho is your favorite team on this list?\n");
    printf("\n1 - Seattle Seahawks?");
    printf("\n2 - San Francisco 49'ers?");
    printf("\n3 - Arizona Cardinals?");
    printf("\n4 - St. Louis Rams?");
    printf("\n");
    printf("\nPlease make your selection and press ENTER\n\n");
    
    scanf("%d", &choice);
    
    if(choice < 1 || choice > 4)
              {
              printf("\nIm sorry, that selection is not valid; you must choose 1,2,3 or 4.\n");
              printf("\nPlease choose a valid selection\n\n");
              }
    }
    while( choice < 1 || choice > 4 );
    
    
    if(choice == 1)
    
              return "Seattle Seahawks.\nEXCELLENT CHOICE.\nThey are the best team in the land.";
    
    if(choice == 2)
    
              return "San Francisco 49'ers.\nThey are a fine team...\nbut not as good as our Seahawks.";
    
    if(choice == 3)
    
              return "Arizona Cardinals.\nA decent team over-all...\nbut not the best team in the land.";
    
    if(choice == 4)
    
              return "St. Louis Rams.\nPerhaps you should choose again...";
    
    
    }

  8. #8
    Registered User
    Join Date
    Nov 2012
    Posts
    11
    Thank you all again very much.

    I went to bed last night without having this resolved. Will sleep well tonight!


  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    You have it mostly fixed. You are still calling main recursively. Remove this line from your code, it is wrong:
    Code:
    return main();
    Instead, use a do-while loop like I suggested before. You can put one loop inside another:
    Code:
    do
    {
        team = best_team();
    
    
        printf("\nYour favorite team on this list is the %s\n\n",team);
        printf("Would you like to choose another team?\n\n");
    
        do {
    
            printf("Enter 1 to choose another team or 0 to quit.\n\n");
            scanf("%d", &again);
     
            if(again < 0 || again >1)
            {
                printf("\nIm sorry, that selection is not valid; you must enter 1 or 0.\n");
                printf("\nPlease enter a valid selection\n\n");
            }
        } while(again < 0 || again >1);
    } while(again == 1);
    system("PAUSE");
    return 0;
    That's it, that's all you need. Read that over carefully and think about the logic there. Remember, a do-while loop always executes at least once, the condition to continue/stop the loop is at the bottom.

  10. #10
    Registered User
    Join Date
    Nov 2012
    Posts
    11
    Quote Originally Posted by anduril462 View Post
    You have it mostly fixed. You are still calling main recursively. Remove this line from your code, it is wrong:
    Code:
    return main();
    Instead, use a do-while loop like I suggested before. You can put one loop inside another:
    Code:
    do
    {
        team = best_team();
    
    
        printf("\nYour favorite team on this list is the %s\n\n",team);
        printf("Would you like to choose another team?\n\n");
    
        do {
    
            printf("Enter 1 to choose another team or 0 to quit.\n\n");
            scanf("%d", &again);
     
            if(again < 0 || again >1)
            {
                printf("\nIm sorry, that selection is not valid; you must enter 1 or 0.\n");
                printf("\nPlease enter a valid selection\n\n");
            }
        } while(again < 0 || again >1);
    } while(again == 1);
    system("PAUSE");
    return 0;
    That's it, that's all you need. Read that over carefully and think about the logic there. Remember, a do-while loop always executes at least once, the condition to continue/stop the loop is at the bottom.
    Gotcha. That looks much better than the way I had it.

    Also, when you say "recursively" does that refer to how the main was being called from within the main? If it was working, why is it a problem? Is it just a bad practice because in some situations it can cause problems?

  11. #11
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by steveryan View Post
    Also, when you say "recursively" does that refer to how the main was being called from within the main?
    Yes, that is what recursively means. There is also indirect recursion, were (for example), main calls some function foo(), which in turn calls main(). Notice main doesn't call itself directly, but it still calls itself in a roundabout way.
    If it was working, why is it a problem? Is it just a bad practice because in some situations it can cause problems?
    Basically, yes. Every time a function calls another function, it places some stuff on the stack. Think of a stack of papers, where each sheet of paper has all the data necessary for the current function: function parameters, local variables, temporary variables, etc. The top-most paper in that stack refers to the current function, the one below it the function that called the current function, on down to the first instance of main. Every time you call a function, you put a piece of paper on the stack with all the data for that function. When the function finishes, you take that paper off the stack. Now, when main calls itself recursively, when the user keeps choosing another team, you keep piling new papers on the stack, but you never finish a call to main, so they just keep piling up. Eventually your stack of papers will hit the ceiling and you're screwed. In computer terms, you run out of space for the stack and your program (probably) crashes, or at least doesn't work well. In practice, that takes many, many, many recursive calls to main, but it's still a potential problem. The loop version, however, doesn't use any extra stack space because it doesn't add anything to the stack, it all happens in the same instance of that function.

    Any recursive solution has this potential problem, so usually you avoid things that can be "infinitely" recursive, like re-running the program. Recursive solutions lend well to finite things like certain data structures, algorithms or calculations. There may be a lot of data, and many layers of recursion, but you are usually sure it will terminate without too many recursive calls.

    tl;dr: if somebody uses your program enough without stopping/restarting, you will run out of memory

  12. #12
    Registered User
    Join Date
    Nov 2012
    Posts
    11
    Quote Originally Posted by anduril462 View Post
    Yes, that is what recursively means. There is also indirect recursion, were (for example), main calls some function foo(), which in turn calls main(). Notice main doesn't call itself directly, but it still calls itself in a roundabout way.

    Basically, yes. Every time a function calls another function, it places some stuff on the stack. Think of a stack of papers, where each sheet of paper has all the data necessary for the current function: function parameters, local variables, temporary variables, etc. The top-most paper in that stack refers to the current function, the one below it the function that called the current function, on down to the first instance of main. Every time you call a function, you put a piece of paper on the stack with all the data for that function. When the function finishes, you take that paper off the stack. Now, when main calls itself recursively, when the user keeps choosing another team, you keep piling new papers on the stack, but you never finish a call to main, so they just keep piling up. Eventually your stack of papers will hit the ceiling and you're screwed. In computer terms, you run out of space for the stack and your program (probably) crashes, or at least doesn't work well. In practice, that takes many, many, many recursive calls to main, but it's still a potential problem. The loop version, however, doesn't use any extra stack space because it doesn't add anything to the stack, it all happens in the same instance of that function.

    Any recursive solution has this potential problem, so usually you avoid things that can be "infinitely" recursive, like re-running the program. Recursive solutions lend well to finite things like certain data structures, algorithms or calculations. There may be a lot of data, and many layers of recursion, but you are usually sure it will terminate without too many recursive calls.

    tl;dr: if somebody uses your program enough without stopping/restarting, you will run out of memory
    Thank you very much for the explanation and your help. It makes much more sense now.

  13. #13
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by steveryan View Post
    Also, when you say "recursively" does that refer to how the main was being called from within the main? If it was working, why is it a problem? Is it just a bad practice because in some situations it can cause problems?
    Yes, recursion refers to a function calling itself. This can be direct (eg main() calling main()) or indirect (main() calling x() which calls main()).

    There are many circumstances in which recursion causes problems. In particular, if all you're doing is trying to loop (start over execution) recursion is an unduly expensive and error prone method - it is better to use a simple loop construct. Calling functions involves overheads (saving registers, use of stack space, etc) that loop constructs do not.

    Oh, if your objective is to learn C++, then you need to know that calling main() from user code (i.e. code you write) is forbidden by the C++ standard.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. nbin=fopen("input.txt","a"); doesn't work?
    By Adam Rinkleff in forum C Programming
    Replies: 2
    Last Post: 06-23-2011, 02:57 PM
  2. Replies: 2
    Last Post: 01-13-2010, 04:58 PM
  3. How to add the "QUIT APPLICTION" code in this???
    By kahwei in forum C Programming
    Replies: 7
    Last Post: 02-06-2009, 10:53 AM
  4. IE7 and Firefox2 "open file" option
    By joelsmit in forum Tech Board
    Replies: 1
    Last Post: 01-11-2007, 03:18 AM
  5. Press "Enter" key to quit the program
    By Vitamin_C in forum C++ Programming
    Replies: 7
    Last Post: 12-18-2005, 08:25 PM