Thread: Nasty Char-Input-into-Int Bug

  1. #1
    Registered User
    Join Date
    Sep 2011
    Posts
    8

    Question Nasty Char-Input-into-Int Bug

    In this array program I have due on Tuesday in my C programming course at school (which includes a menu function), I have tested this compiled program for any bugs. One major problem I found is the endless cycling of program code that occurs when I enter a non-integer character into the program (the input code is programmed for an integer). This only occurs when I enter a letter or a symbol, but not a number (I've programmed an error message for any numbers other than 1, 2, 3, or 4 in the main function, or 1, 2, or 3 in the third function). Does anyone know code I should insert so that any non-integer char characters that are entered will, instead of causing the program to crash, return an error message and recall the menu?

    Here is my code (first my own header file, and then the C file)

    Code:
    int pointsNFL2010 [2][2][2] =
    {
    {
    {518, 375},
    {435, 366}
    },
    {
    {414, 334},
    {439, 310}
    }
    };
    Code:
    #include <stdio.h>
    #include "football.h"
    
    int sel, score, score1, score2, afcScore, nfcScore, i, j, k;
    int *value, *value1, *value2, *afc1, *nfc1;
    int pointsTotal();
    int pointsConference();
    int pointsTeam();
    
    int main(void)
    {
                    printf("MENU\n");
                    printf("------------\n");
                    printf("Welcome! This program lets you view statistics for total team points scored in the NFL during the 2010 regular teams. Points are given for the four division winners in each conference (AFC and NFC) in total 'Points For' (PF), and sorted out in order of seed in playoffs (in AFC: New England Patriots, Pittsburgh Steelers, Indianapolis Colts, Kansas City Chiefs; in NFC: Atlanta Falcons, Chicago Bears, Philadelphia Eagles, Seattle Seahawks). Points can be viewed by league totals, conference totals, or by individual team.\n");
                    printf("------------\n");
                    printf("Which statistic would you like to view?\n");
                    printf("------------\n");
                    printf("1) Total points scored by all teams\n");
                    printf("2) Total points scored by conference\n");
                    printf("3) Total points scored by individual team\n");
                    printf("4) EXIT\n");
                    printf("------------\n");
                    printf("Enter a selection above: ");
                    scanf("%d", &sel);
    while (sel != 4)
                    {
                            {
                            if (sel == 1)
                                    pointsTotal();
                            else if (sel == 2)
                                    pointsConference();
                            else if (sel == 3)
                                    pointsTeam();
                            else
                                    printf("\nError! Please try again!\n\n");
                            }
                            printf("\n------------\n");
                            printf("Which statistic would you like to view?\n");
                            printf("------------\n");
                            printf("1) Total points scored by all teams\n");
                            printf("2) Total points scored by conference\n");
                            printf("3) Total points scored by individual team\n");
                            printf("4) EXIT\n");
                            printf("------------\n");
                            printf("Enter a selection above: ");
                            scanf("%d", &sel);
                    }
            printf("\nPeace out.\n");
    
            return 0;
    }
    
    int pointsTotal()
    {
            printf("\nThis function gives you the combined score for all 8 division winners.\n");
            for (i = 0; i < 2; i++){
                    for (j = 0; j < 2; j++){
                            for (k = 0; k < 2; k++){
                                    value = &pointsNFL2010[i][j][k];
                                    score += *value;
            }
            }
            }
            printf("\nThe total points scored by all 8 division winners in 2010 is %d.\n\n", score);
    
            return 1;
    }
    
    int pointsConference()
    {
            printf("\nThis function breaks down the combined score of all 8 division winners into their respective conferences.\n");
            for (i = 0; i < 1; i++){
                    for (j = 0; j < 2; j++){
                            for (k = 0; k < 2; k++){
                                    afc1 = &pointsNFL2010[0][j][k];
                                    afcScore += *afc1;}
    
            }}
            for (i = 1; i < 2; i++){
                    for (j = 0; j < 2; j++){
                            for (k = 0; k < 2; k++){
                                    nfc1= &pointsNFL2010[1][j][k];
                                    nfcScore += *nfc1;}
            }}
            printf("\nThe total points scored is %d by the AFC and %d by the NFC.\n\n", afcScore, nfcScore);
    
            return 1;
    
    }
    
    int pointsTeam()
    {
            int t;
    
            printf("\nThis function displays total points scored for two teams (one in AFC, one in NFC). For example, if you pick 1, the total points scored for the number 1 seeded teams in both the AFC and NFC will each be displayed separately.\n");
            printf("Which ranking would you like to see? Enter 1, 2, 3, or 4 :\n");
            scanf("%d", &t);
            if (t == 1)
            {
                    value1 = &pointsNFL2010[0][0][0];
                    value2 = &pointsNFL2010[0][0][1];
                    score1 = *value1;
                    score2 = *value2;
                    printf("\nThe scores for the teams ranked at the number specified are %d and %d (AFC and NFC, respectively).\n\n", score1, score2);
            }
            else if (t == 2)
            {
                    value1 = &pointsNFL2010[0][1][0];
                    value2 = &pointsNFL2010[0][1][1];
                    score1 = *value1;
                    score2 = *value2;
                    printf("\nThe scores for the teams ranked at the number specified are %d and %d (AFC and NFC, respectively).\n\n", score1, score2);
            }
            else if (t == 3)
            {
                    value1 = &pointsNFL2010[1][0][0];
                    value2 = &pointsNFL2010[1][0][1];
                    score1 = *value1;
                    score2 = *value2;
                    printf("\nThe scores for the teams ranked at the number specified are %d and %d (AFC and NFC, respectively).\n\n", score1, score2);}
            else if (t == 4)
            {
                    value1 = &pointsNFL2010[1][1][0];
                    value2 = &pointsNFL2010[1][1][1];
                    score1 = *value1;
                    score2 = *value2;
                    printf("\nThe scores for the teams ranked at the number specified are %d and %d (AFC and NFC, respectively).\n", score1, score2);
            }
            else
                    printf("\nError! Back to the main menu to try again!\n\n");
    
            return 1;
    }
    For the record, I should say that I attempted to change the input type to straight-up char (it wouldn't compile because it still regarded 1, 2, 3, 4, as ints), so when I changed them to letters a, b, c, and d (thinking I could then put code in to call the error message for any entry other than a, b, c, or d), the menu function would not run properly. This is the only way for me to get the program to run properly (with int input type).
    Last edited by kowit010; 09-17-2011 at 08:18 PM.

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    If scanf() fails to receive the desired input, in leaves whatever it found in the input stream there, creating a cascading effect in your case.

    scanf() returns zero if it fails to receive the desired input.
    Devoted my life to programming...

  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    If you are only getting a single character use...
    Code:
    int quit = 0;
    while (! quit) 
      {
        // display menu
    
       switch ( getchar() )
         { 
    
             // valid cases here
    
    
            case '\n" :
               break ;
            default :
               printf("That entry is not valid\n"); 
    
    } 
    }

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Sipher View Post
    scanf() returns zero if it fails to receive the desired input.
    ..in this case.

    Technically, it returns the number of successful items assigned. If it returns 0, then it means it saw some input and didn't store any of it. It can also return EOF.


    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    Quote Originally Posted by quzah View Post
    Technically, it returns the number of successful items assigned. If it returns 0, then it means it saw some input and didn't store any of it. It can also return EOF.
    Oh sorry, I didn't know that. I assumed what I said because of code like this:
    Code:
    if (!scanf(..., ...))
        whatever;
    Devoted my life to programming...

  6. #6
    Registered User
    Join Date
    Sep 2011
    Posts
    8
    Quote Originally Posted by CommonTater View Post
    If you are only getting a single character use...
    Code:
    int quit = 0;
    while (! quit) 
      {
        // display menu
    
       switch ( getchar() )
         { 
    
             // valid cases here
    
    
            case '\n" :
               break ;
            default :
               printf("That entry is not valid\n"); 
    
    } 
    }
    I tried that and it made no difference. Any integer I used yields me the error message and it still does the cascading error when I enter a letter or symbol.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What exactly did you try? What is your current code?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Sep 2011
    Posts
    8
    Quote Originally Posted by laserlight View Post
    What exactly did you try? What is your current code?
    Like this stuff posted above:

    Code:
    int quit = 0;
    while (! quit) 
      {
        // display menu
    
       switch ( getchar() )
         { 
    
             // valid cases here
    
    
            case '\n" :
               break ;
            default :
               printf("That entry is not valid\n"); 
    
    } 
    }

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by kowit010 View Post
    I tried that and it made no difference. Any integer I used yields me the error message and it still does the cascading error when I enter a letter or symbol.
    What exactly did you try?
    The example I gave you is a skeletal version of code I use in real world programming. I know it works.


    Code:
    #include <stdio.h>
    
    int main(void)
      {
        printf("Statistics viewer...\n");
        printf("Which would you like to view?\n");
        printf("------------\n");
        printf("1) Function 1\n");
        printf("2) Function 2\n");
        printf("3) Function 3\n");
        printf("4) EXIT\n");
        printf("------------\n");
        printf("Enter a selection from the menu (1, 2, 3 or 4) : ");
         
        while (1)
           {
              switch ( getchar() )
                {  
                   case '1' :
                      printf("function 1\n");  // call function 1 here
                      break;
                   case '2' :
                      printf("function 2\n");  // call function 2 here
                      break;
                   case '3' : 
                      printf("function 3\n");  // call function 3 here
                     break;
                   case '4' :
                     printf("\nAloha!\n");
                     exit(0);
                   case '\n' :
                     printf("Enter a selection from the menu (1, 2, 3 or 4) : ");
                     break;
                   default :
                      printf("\nError! Please try again!\n\n");
              }
           }
       return 0;
    }
    Last edited by CommonTater; 09-18-2011 at 08:44 AM. Reason: Tested and re-pasted...

  10. #10
    Registered User
    Join Date
    Sep 2011
    Posts
    8
    Quote Originally Posted by kowit010 View Post
    Like this stuff posted above:

    Code:
    int quit = 0;
    while (! quit) 
      {
        // display menu
    
       switch ( getchar() )
         { 
    
             // valid cases here
    
    
            case '\n" :
               break ;
            default :
               printf("That entry is not valid\n"); 
    
    } 
    }
    What commontater posted, that is

  11. #11
    Registered User
    Join Date
    Sep 2011
    Posts
    8
    Quote Originally Posted by CommonTater View Post
    What exactly did you try?
    The example I gave you is a skeletal version of code I use in real world programming. I know it works.


    Code:
    int main(void)
      {
        printf(Statistics viewer...\n");
        printf("Which statistic would you like to view?\n");
        printf("------------\n");
        printf("1) Total points scored by all teams\n");
        printf("2) Total points scored by conference\n");
        printf("3) Total points scored by individual team\n");
        printf("4) EXIT\n");
        printf("------------\n");
         
        while (sel != 4)
           {
              printf("Enter a selection from the menu (1, 2, 3 or 4) : ");
              switch ( getchar() )
                {  
                   case '1' :
                      pointsTotal();
                      break;
                   case '2' :
                      pointsConference();
                      break;
                   case '3' : 
                     pointsTeam();
                     break;
                   case '4' :
                     printf("\nAloha!\n"
                     exit(0);
                   case '\n' :
                     break;
                   default :
                      printf("\nError! Please try again!\n\n");
              }
           }
       return 0;
    }
    That's exactly the model I used and it made absolutely no difference. The getchar() function is causing problems for me which is why I have to use int.

  12. #12
    Registered User
    Join Date
    Sep 2011
    Posts
    8
    Quote Originally Posted by kowit010 View Post
    That's exactly the model I used and it made absolutely no difference. The getchar() function is causing problems for me which is why I have to use int.
    Nope, that didn't work because now I cannot exit when I enter 4.

  13. #13
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by kowit010 View Post
    Nope, that didn't work because now I cannot exit when I enter 4.
    Go back and look at post #9 ... I tested that on my own system and it works just fine.

    Stop reposting what I posted... Post your *actual* code... lets see what you are doing wrong!
    Last edited by CommonTater; 09-18-2011 at 08:48 AM.

  14. #14
    Registered User
    Join Date
    Sep 2011
    Posts
    8
    Quote Originally Posted by kowit010 View Post
    Nope, that didn't work because now I cannot exit when I enter 4.
    When I do this:

    Code:
    int main(void)
    {
    	menu();
    	while (ch != '4')
    	{	
    		switch (getchar())	
    		{
    		case '1':
    			pointsTotal();
    			break;
    		case '2':
    			pointsConference();
    			break;
    		case '3':
    			pointsTeam();
    			break;
    		default:
    			printf("\nInvalid entry! Please try again!\n\n");
    			break;
    		}
    		menu();
    		ch = getchar();
    	}
    	
    	printf("\nPeace out.\n");
    	
    	return 0;
    }
    And I enter 4, this is what I get:

    "Invalid entry! Please try again!"

    I cannot exit the program without doing ^C interrupt. Even after adding the "case '\n'" in there, it made no difference.
    Last edited by kowit010; 09-18-2011 at 08:54 AM. Reason: Adding another detail

  15. #15
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,739
    Code:
    switch (getchar())
    should be:

    Code:
    switch (ch)
    Devoted my life to programming...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Something Nasty
    By string in forum C Programming
    Replies: 4
    Last Post: 06-01-2008, 01:28 PM
  2. How can terminate input when input specifed char?
    By Mathsniper in forum C Programming
    Replies: 5
    Last Post: 12-11-2006, 09:59 AM
  3. Function input may char or char[] ..?
    By GSalah in forum C++ Programming
    Replies: 2
    Last Post: 11-15-2006, 04:07 AM
  4. Nasty looking thing
    By richard_hooper in forum C Programming
    Replies: 3
    Last Post: 05-27-2005, 09:40 AM

Tags for this Thread