Thread: Replacing switch statement with a nested if/else

  1. #16
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by CommonTater View Post
    You still need "else if" for your final clause.
    That's not true.
    Aren't if-else statements something that you would learn in about your first week programming? Back to the books man.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  2. #17
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by Char*Pntr View Post
    Just curious, did you try to compile the change with your suggestion? When I read this,
    I went scrambling back around 5 chapters in my C book to check this out. There I found out, that with multiple "else if" the last part of that structure ends with just an "else".
    Hermmmm... On your prompting I did just that... and guess what?

    You are right and I was wrong.

    Sorry about that....

    (Now to check a couple of trouble spots in some of my older code... )

  3. #18
    Registered User
    Join Date
    Aug 2010
    Posts
    8
    Thanks all for your help. I am learning C on my own, still on the loop control chapters and I'm using Code Block with mingw as compiler.

    I have added this line to deal with space and newline:

    Code:
    else if ( grade == '\n' || grade == ' ' )
         continue;
    Here's the full exercise:

    Rewrite the program of Fig. 4.7 by replacing the switch statement with a nested if/else statement, be careful to deal with the default case properly. The rewrite this new version by replacing the nested if/else statement with a series of if statements; here too, be careful to deal with the default case properly (this is more difficult than in the nested if/else statement version). This exercise demonstrates that switch is a convenience and that any switch statement can be written with only single-selection statements.

    fig. 4.7:
    Code:
    /* Fig. 4.7: fig04_07.c
       Counting letter grades */
    #include <stdio.h>
    
    int main()
    {
       int grade;
       int aCount = 0, bCount = 0, cCount = 0, 
           dCount = 0, fCount = 0;
    
       printf(  "Enter the letter grades.\n"  );
       printf(  "Enter the EOF character to end input.\n"  );
    
       while ( ( grade = getchar() ) != EOF ) {
    
          switch ( grade ) {    /* switch nested in while */
    
             case 'A': case 'a':  /* grade was uppercase A */
                ++aCount;         /* or lowercase a */
                break;
    
             case 'B': case 'b':  /* grade was uppercase B */
                ++bCount;         /* or lowercase b */
                break;
    
             case 'C': case 'c':  /* grade was uppercase C */
                ++cCount;         /* or lowercase c */
                break;
    
             case 'D': case 'd':  /* grade was uppercase D */
                ++dCount;         /* or lowercase d */
                break;
    
             case 'F': case 'f':  /* grade was uppercase F */
                ++fCount;         /* or lowercase f */
                break;
    
             case '\n': case' ':  /* ignore these in input */
                break;
    
             default:        /* catch all other characters */
                printf( "Incorrect letter grade entered." ); 
                printf( " Enter a new grade.\n" ); 
                break;
          }
       }
    
       printf( "\nTotals for each letter grade are:\n" );
       printf( "A: %d\n", aCount );
       printf( "B: %d\n", bCount );
       printf( "C: %d\n", cCount );
       printf( "D: %d\n", dCount );
       printf( "F: %d\n", fCount );
    
       return 0;
    }
    
    
    
    /**************************************************************************
     * (C) Copyright 2000 by Deitel & Associates, Inc. and Prentice Hall.     *
     * All Rights Reserved.                                                   *
     *                                                                        *
     * DISCLAIMER: The authors and publisher of this book have used their     *
     * best efforts in preparing the book. These efforts include the          *
     * development, research, and testing of the theories and programs        *
     * to determine their effectiveness. The authors and publisher make       *
     * no warranty of any kind, expressed or implied, with regard to these    *
     * programs or to the documentation contained in these books. The authors *
     * and publisher shall not be liable in any event for incidental or       *
     * consequential damages in connection with, or arising out of, the       *
     * furnishing, performance, or use of these programs.                     *
     *************************************************************************/
    Last edited by dev123; 09-05-2010 at 12:28 PM.

  4. #19
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    You only want a single character, so a better way to deal with the unwanted characters/newline issue is to eat them all up like this after getting the first character in grade:

    Code:
    int dummy; // outside of loop
    ...
    while ((dummy = getchar()) != '\n') ;
    So with input like this:
    Code:
    Enter the EOF character to end input.
    a
    b
    c     dedsdfwrewrwrewrwedsfw
    a
    c
    ^D
    You end up with output like this:
    Code:
    Totals for each letter grade are:
    A: 2
    B: 1
    C: 2
    D: 0
    F: 0

  5. #20
    Registered User
    Join Date
    Aug 2010
    Posts
    8
    Quote Originally Posted by rags_to_riches View Post
    You only want a single character, so a better way to deal with the unwanted characters/newline issue is to eat them all up like this after getting the first character in grade:

    Code:
    int dummy; // outside of loop
    ...
    while ((dummy = getchar()) != '\n') ;
    So with input like this:
    Code:
    Enter the EOF character to end input.
    a
    b
    c     dedsdfwrewrwrewrwedsfw
    a
    c
    ^D
    You end up with output like this:
    Code:
    Totals for each letter grade are:
    A: 2
    B: 1
    C: 2
    D: 0
    F: 0

    That's a good way of doing it. How to deal with default using only if statements?

  6. #21
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Create a boolean flag that is set to true, e.g., use an int variable initialised to 1. Set this boolean flag to false for each case (e.g., assign 0 to the int variable). Use this flag to check for the default case.
    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

  7. #22
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    I'd do something like this:

    Code:
      
           while ( ( grade = getchar() ) != EOF ) {
          if( grade == 'a' || grade == 'A') {
                aCount++;
                continue;
           }
           /* b,c, etc ... */
          if( grade == '\n' || grade == ' ') {
               continue;
          }
            /* now default */
    You would flush unwanted characters as suggested by rags_to_riches.

  8. #23
    Registered User Char*Pntr's Avatar
    Join Date
    Sep 2007
    Location
    Lathrop, CA
    Posts
    198

    Cool One Possible Solution

    My code below. My biggest inspiration for solving this was due to Rags_to_Riches and laserlight suggestions. Also I found out, the initial problem at hand was not-so-trivial.

    My biggest problem was, that I thought the EOF for my home system was ( ctrl^C + Enter ).

    It wasn't. I just found out by accident, that it's ( ctrl^z + Enter). I've spent many hours thinking that the code was wrong, when I was only using the wrong escape sequence.

    Anyway, I learned a lot from this, and spent the last day pushed back to the beginning pages
    of my C book - dealing with keyboard input.

    I'm saving this code for future reference.

    Code:
    #include <stdio.h>
    
    int main()
    {
       int grade;
       int aCount = 0, bCount = 0, cCount = 0,
           dCount = 0, fCount = 0;
    
       char junk[80];
    
       printf(  "Enter the letter grades.\n"  );
       printf(  "Enter the EOF character to end input.\n\n"  );
       	   
    
       while ( (grade = fgetc(stdin)) != EOF )	// on my home system, EOF character is invoked
       {								// by  ( ctrl^z + ENTER ) sequence
          if ( grade == 'A' || grade == 'a' )
         {
    	     aCount++;
    		  getchar();	// chomps out the extra '\n'  per Rags_To_Riches
          }
    
          else if ( grade == 'B' || grade == 'b' )
          {
                bCount++;
    	    getchar();
           }
    
          else if ( grade == 'C' || grade == 'c' )
         {
             cCount++;
    	 getchar();
         }
    
          else if ( grade == 'D' || grade == 'd' )
          {
               dCount++;
    	   getchar();
          }
    
          else if ( grade == 'F' || grade == 'f' )
          {
               fCount++;
    	   getchar();
           }
    
          else
          {
              printf( "Incorrect letter grade entered." );
              printf( " Enter a new grade.\n" );		
    	  gets(junk);	// gets rid of many extra chars
          }
    
       }
    
       printf( "\nTotals for each letter grade are:\n\n" );
       printf( "A: %d\n", aCount );
       printf( "B: %d\n", bCount );
       printf( "C: %d\n", cCount );
       printf( "D: %d\n", dCount );
       printf( "F: %d\n", fCount );
    
       printf("\n\n");
       return 0;
    }
    Last edited by Char*Pntr; 09-05-2010 at 05:23 PM. Reason: improper display inside the code....format

  9. #24
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Code:
     gets(junk);	// gets rid of many extra chars
    No, no, no, no, NO!!! NO gets()!!!

  10. #25
    Registered User Char*Pntr's Avatar
    Join Date
    Sep 2007
    Location
    Lathrop, CA
    Posts
    198

    Smile

    Quote Originally Posted by rags_to_riches View Post
    Code:
     gets(junk);	// gets rid of many extra chars
    No, no, no, no, NO!!! NO gets()!!!
    I found that using gets() was quite useful in case the user entered multiple characters.

    And reading the OP's requirement, it did not say that gets() could not be used.

    But I have faith that you have a valid reason.. so I'm off now to delete that part
    of offending code, with another small routine without using gets().

    Thanks for your input.

  11. #26
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You have no idea how much "junk" there is in the input buffer! This is a time bomb!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #27
    Registered User Char*Pntr's Avatar
    Join Date
    Sep 2007
    Location
    Lathrop, CA
    Posts
    198

    Smile

    OK, I am posting my final version without the offending gets() function. The changes to the code are highlighted in green.

    Quote Originally Posted by laserlight View Post
    It is simple enough to implement that without resorting to undefined behaviour, e.g.,
    Code:
    int c;
    while ((c = fgetc(stdin)) != EOF && c != '\n');
    When I read the above, I knew there was more there than replying on the "merits of undefined behaviour" to a pervious poster. I knew that laserlight was also giving us a clue on how to handle extra chars from STDIN.

    After making the changes, I tried to "break" the code. On one input, I typed in "qwerty" and the
    code handled that appropriately.

    here's the code:

    Code:
    //   9/5/10
    //
    
    #include <stdio.h>
    
    int main()
    {
       int grade, TestChar;  // Test Char used as a condition to clear STDIN invalid chars
       int aCount = 0, bCount = 0, cCount = 0,
           dCount = 0, fCount = 0;
    
       printf(  "Enter the letter grades.\n"  );
       printf(  "Enter the EOF character to end input.\n\n"  );
       	   
       while ( (grade = fgetc(stdin)) != EOF )	// on my home system, EOF character is invoked
       {								// by  ( ctrl^z + ENTER ) sequence
          if ( grade == 'A' || grade == 'a' )
         {
    	     aCount++;
    	     getchar();	 // chomps out the extra '\n'  per Rags_To_Riches
          }
    
          else if ( grade == 'B' || grade == 'b' )
          {
                 bCount++;
    	     getchar();
           }
    
          else if ( grade == 'C' || grade == 'c' )
         {
                cCount++;
                getchar();
         }
    
          else if ( grade == 'D' || grade == 'd' )
          {
                dCount++;
    	    getchar();
          }
    
          else if ( grade == 'F' || grade == 'f' )
          {
                fCount++;
    	    getchar();
           }
    
          else
          {
                printf( "Incorrect letter grade entered." );
                printf( " Enter a new grade.\n" );
    
    	      do
    		  {
    			TestChar = getc(stdin);
    		  }
    		  while ( TestChar != EOF && TestChar != '\n' );	// using laserlight's previous example :-)
          }
       }
    
       printf( "\nTotals for each letter grade are:\n\n" );
       printf( "A: %d\n", aCount );
       printf( "B: %d\n", bCount );
       printf( "C: %d\n", cCount );
       printf( "D: %d\n", dCount );
       printf( "F: %d\n", fCount );
    
       printf("\n\n");
       return 0;
    }

  13. #28
    Registered User Char*Pntr's Avatar
    Join Date
    Sep 2007
    Location
    Lathrop, CA
    Posts
    198

    Smile

    Quote Originally Posted by Elysia View Post
    You have no idea how much "junk" there is in the input buffer! This is a time bomb!
    Thanks, you made me smile. :-)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Switch statement / default:
    By kcpilot in forum C Programming
    Replies: 4
    Last Post: 12-02-2008, 03:14 PM
  2. Getting the switch statement to work.
    By mtymightymike in forum C Programming
    Replies: 7
    Last Post: 10-15-2008, 06:32 PM
  3. Stack operations from switch statement elements
    By mlsrar in forum C Programming
    Replies: 15
    Last Post: 10-02-2008, 01:12 PM
  4. Switch Statement
    By DarkDot in forum C++ Programming
    Replies: 11
    Last Post: 03-28-2007, 10:11 PM
  5. Uh-oh! I am having a major switch problem!
    By goodn in forum C Programming
    Replies: 4
    Last Post: 11-01-2001, 04:49 PM