Thread: Loop with Scanf / switch statement causing weird output

  1. #1
    Registered User
    Join Date
    Jun 2011
    Posts
    41

    Angry Loop with Scanf / switch statement causing weird output

    creating a validation check to ensure the cards entered are correct. It works when the cards are entered correctly the first time. After an invalid entry, the cards store the default value in a switch statement and always cause an error...



    Code:
     
    #include <stdio.h>
    #include <stdbool.h>
    
    int main()
    {
        int j, i, k, n = 5, check = 2;
    
        char hands[2][5];
        int nhands[2][5];
        int first_hand[5];
        int second_hand[5];
        int count[14];
    
       /* Loop until it is validated */
           while(check == 2){  
           printf("\nPlease enter a hand of 5 card poker for 2 players. Format HHHHH HHHHH\n");
        /* Get the cards */
           scanf("%c%c%c%c%c %c%c%c%c%c", &hands[0][0], &hands[0][1], &hands[0][2], &hands[0][3], &hands[0][4], &hands[1][0], &hands[1][1], &hands[1][2], &hands[1][3], &hands[1][4]);
         
       /* Change the char values to numerical values for easier testing */  
        for(j = 0; j<2; j++){
           for(i = 0; i<5; i++){
           switch(hands[j][i]){
             default  : nhands[j][i] = 15; break; 
             case 'A' : nhands[j][i] = 14; break;
             case 'K' : nhands[j][i] = 13; break;
             case 'Q' : nhands[j][i] = 12; break;
             case 'J' : nhands[j][i] = 11; break;
             case '0' : nhands[j][i] = 10; break;
             case '9' : nhands[j][i] = 9; break;
             case '8' : nhands[j][i] = 8; break;
             case '7' : nhands[j][i] = 7; break;
             case '6' : nhands[j][i] = 6; break;
             case '5' : nhands[j][i] = 5; break;
             case '4' : nhands[j][i] = 4; break;
             case '3' : nhands[j][i] = 3; break;
             case '2' : nhands[j][i] = 2; break; 
             
             }     
           }
        }
        
        for(k=0; k<14; k++){
            count[k] = 0;
            check = 1;
        }
        /* Checks for invalid card types entered */
        for(j = 0; j<2; j++){
           for(i = 0; i<5; i++){
               if(nhands[j][i] == 15){ 
                   check = 2; 
                   printf("You entered an invalid card, please retype your hand");
                       
                       /*debug */
                       for(j = 0; j<2; j++){
                             for(i = 0; i<5; i++){
                                   printf("\ncard %d: %d", i+1, nhands[j][i]);
                             }
                       }
               }           
           }
        }
        /* Checks for more than 4 of the same card type */
        for(k = 0; k<14; k++){
              for(j = 0; j<2; j++){
                    for(i = 0; i<5; i++){
                       if(nhands[j][i] == (k+2)){ count[k] = count[k] + 1; }
                    } 
              }
              if( count[k] > 4) { 
                  check = 2;
                  printf("You entered too many of the same card, please retype your hand");                     
              }
              
        } 
    }   
    getch();
    return 0;
    }
    Last edited by Oonej; 06-08-2011 at 11:06 AM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,712
    Cprogramming.com FAQ > Flush the input buffer
    scanf with %c reads every character, including newlines.
    Most other format conversions skip over white space (including newlines).

    It would be better if you used fgets() to read into a large buffer, then extracted what you wanted from the line in memory. It saves an awful lot of trying to tidy up the input stream.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2011
    Posts
    41
    My problem is, we haven't learned fgets() yet, i'm takign a class for c programming.. so we are limited on what we can use for our project

  4. #4
    Registered User
    Join Date
    Jun 2011
    Posts
    41
    is there any way to do what you suggest without using fgets() or clearing the input buffer?

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,712
    You could call scanf(%c) one more time to eat the \n.

    But you're still extremely dependent on the user cooperating with the input your program expects.

    I hope your tutor gets around to fgets() pretty soon...
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Jun 2011
    Posts
    41
    we aren't getting to them for another 2 weeks or so.

    I'm in class atm, i'll ask him about it after class today.

    but whats also weird is the program starts ignoring the empty space between the 2 hands as well, and counts that as an "invalid character" and defaulting the value of it to 15. ( the default character we assign to invalid characters )...

    it seems to be card 1 of player 1 and card 2 of player 2...

    thanks for any more help

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,712
    > default : nhands[j][i] = 15; break;
    I would suggest you add something like
    Code:
    printf("Found bad character %c(%d)\n", hands[j][i], hands[j][i] );
    so you can see exactly what you're getting.

    And from that, perhaps figure out what input caused it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Jun 2011
    Posts
    41
    Output:

    Please enter a hand of 5 card poker for 2 players. Format HHHHH HHHHH
    22222 33547 <- my input

    You entered too many of the same card, please retype your hand.
    card 1: 2, 2 <- format : card number: number, character
    card 2: 2, 2
    card 3: 2, 2
    card 4: 2, 2
    card 5: 2, 2
    card 1: 3, 3
    card 2: 3, 3
    card 3: 5, 5
    card 4: 4, 4
    card 5: 7, 7
    Please enter a hand of 5 card poker for 2 players. Format HHHHH HHHHH
    22233 65778 <- my input

    card 1: 15, <- putting a \n value here?
    <- actual space here, due to \n?
    card 2: 2, 2
    card 3: 2, 2
    card 4: 2, 2
    card 5: 3, 3
    card 1: 3, 3
    card 2: 15, <- if the previous one wasn't entered, this shouldn't appear
    card 3: 6, 6
    card 4: 5, 5
    card 5: 7, 7 <- truncating the remaining 2

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Easy fix: put a space before your %c%c%c%c%c (just as you have a space between the two sets) to deal with stray enter-keys.

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You need to consume the newline then after you read the hand.
    Code:
    int readhands( char hand1[5], char hand2[5] )
    {
        int rval = 0;
        printf( "Enter two hands in this format: CCCCC CCCCC\n" );
        rval = scanf( "%c%c%c%c%c %c%c%c%c%c%*[^\n]\n",
            &hand1[ 0 ], &hand1[ 1 ], &hand1[ 2 ], &hand1[ 3 ], &hand1[ 4 ]
            &hand2[ 0 ], &hand2[ 1 ], &hand2[ 2 ], &hand2[ 3 ], &hand2[ 4 ] );
        return rval == 10;
    }
    Something like that looks like it should work.


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

  11. #11
    Registered User
    Join Date
    Jun 2011
    Posts
    41
    Sweet, it works now Thanks guys!

    Yeah I can't wait to get ti fgets() !!! this scanf nonsense is annoying

  12. #12
    Registered User
    Join Date
    Jun 2011
    Posts
    41
    ok after adding a second loop to varify if they want to continue or not, i'm getting more errors, We must request a Y or N scanf to see if the player wants to continue testing hands...

    When i press y it is stored within the first element of the array, followed by a \n .... if someone can further explain how to use the buffer code, i will happily implement that and tell my teach to eat one.

    This is the code i'm referring to:
    Code:
    int main(void)
    {
      int   ch;
      char  buf[BUFSIZ];
      
      puts("Flushing input");
      
      while ((ch = getchar()) != '\n' && ch != EOF);
      
      printf ("Enter some text: ");
      
      if (fgets(buf, sizeof(buf), stdin))
      {
        printf ("You entered: %s", buf);
      }
      
      return 0;
    }
    sorry for the noob question, just not familiar with this process...

    thanks for any help! hopefully you can save some frustration!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. scanf with switch statement, weird behavior
    By ademkiv in forum C Programming
    Replies: 1
    Last Post: 11-22-2010, 10:49 AM
  2. Weird output of scanf and printf.
    By omnificient in forum C Programming
    Replies: 2
    Last Post: 12-05-2007, 01:28 PM
  3. Switch statement and returning the correct output
    By slowcoder in forum C Programming
    Replies: 6
    Last Post: 09-28-2006, 04:00 PM
  4. Switch statement = infinite loop
    By Lucid003 in forum C++ Programming
    Replies: 10
    Last Post: 10-10-2005, 12:46 AM
  5. switch statement that uses loop
    By mike in forum C++ Programming
    Replies: 2
    Last Post: 02-22-2002, 05:47 PM