Thread: Switch statement does not flow through cases

  1. #1
    Registered User
    Join Date
    Jul 2012
    Posts
    55

    Switch statement does not flow through cases

    I am brand new to programming (2 weeks strong ). I have to use a switch statement to output characters, lines and words. I have been using the same if statements for th assignment (while, do-while) without any issue.

    Can someone help point me in the correct direction. When I run the code I enter text and if I hit enter it immediately breaks and prints output - expect it does not increment anything. All results are 0.

    If I type the word 'test' in the other loops hitting enter would bring me to a new line to continue entering text. Now it just breaks and terminates. I tried removing the break; after each case but still get the same result.

    I appreciate the help.

    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    
    #define IN 1
    #define OUT 0
    
    
    int main()
    {
    	int c, line_count, word_count, character_count, state, choice;
    
    
    	state = OUT;
    	line_count = word_count = character_count = 0;
    	
    	c = getchar();
    
    
    	switch (c)
    	{
    		if(isalpha(c) && c != ' ' && c != '\n')
    			choice = 1;
    	case '1':
    		++character_count;
    		break;
    		
    		if(c == ' ' || c == '\n' || c == '\t')
    			state = OUT; 
    		else if(isalpha(c) && state == OUT)
    		{
    			state = IN;
    		}
    			choice = 2;
    	case '2':
    		++ word_count;
    		break;
    	
    	case '\n':
    		++line_count;
    		break;
    		
    	default:
    		if(c == '4')
    			break;
    	}
    	
    	getchar();
    
    
    	printf("Lines:%d\nWords:%d\nChraracters:%d\n", line_count, word_count, character_count);
    	
    }

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    Code:
        switch (c)
        {
            if(isalpha(c) && c != ' ' && c != '\n')
                choice = 1;
    it is always going to skip this code before the first 'case'. and the code at line 28 will never be executed because of the 'break' on line 26 which will exit the switch statement.

    although it is legal to put code in arbitrary places in a switch statement, it is bad style and leads to this type of problem. you switch statements should simply be like
    Code:
    switch(value) {
    case 1:
       ...code
       break;
    case 2:
       ...code
       break;
    default:
       ...code
       break;
    }
    so that it follows a strict order of executing a single case then a break.

    edit: the switch logic should read just like
    Code:
    if (condition 1) {
       ..code
    } else if (condition 2) {
       ...code
    }
    else {
       ...code
    }
    I'm not saying code it like that, using a switch is good. it should just follow that flow.
    Last edited by dmh2000; 07-26-2012 at 10:50 AM.

  3. #3
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    If you want it to loop through all the characters then you still need a while-loop around the whole thing.

    You are keeping too much of your old "if-based" code, making a mess of your switch statment.

    Get rid of the "choice" variable.

    Your switch should look something like this:
    Code:
    switch (c)
    {
    case ' ':
    case '\t':
        // A word has ended (if you were in one).
        break;
    case '\n':
        // A word has ended (if you were in one).
        // A line has ended.
        break;
    default:
        // c is a "word" char (any char that is not space, tab, or newline)
        break;
    }
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  4. #4
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    Thanks - that was helpful - I made the changes - now I get an infinite loop. If I type 'test' - infinite loop w/ Characters 1 (should be four) Lines:0 Words:0 - this happens w and w/o break;

    Code:
    #include <stdio.h>#include <ctype.h>
    
    
    #define IN 1
    #define OUT 0
    
    
    int main()
    {
    	int c, line_count, word_count, character_count, state;
    
    
    	state = OUT;
    	line_count = word_count = character_count = 0;
    	
    	c = getchar();
    
    
    	switch (c)
    	{
    	case ' ':
    	case '\t':
    		if(c == ' ' || c == '\t')
    			state = OUT;
    		else if(isalpha(c) && state == OUT)
    			{
    				state = IN;
    				++word_count;
    			}
    	case '\n':
    		if(c == '\n')
    			state = OUT;
    		else if(isalpha(c) && state == OUT)
    			{
    				state = IN;
    				++word_count;
    			}
    			++line_count;
    	default:
    		if(isalpha(c) && c!=' ' && c != '\n' && c != '\t')
    			++character_count;
    		break;
    	}
    
    
    	while(c != EOF && c != '4')
    
    
    	
    	printf("Lines:%d\nWords:%d\nChraracters:%d\n", line_count, word_count, character_count);
    	return 0;
    	
    }

  5. #5
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    you should have 'break' before each case. right now each case in the switch falls through to the next one. thats not causing the loop problem though.
    your while look only includes the printf on line 50. you probably want the 'while' statement before line 16, with braces enclosing down through the end of the switch statement. go back and read through how 'while' statements work.

  6. #6
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    It works now.

    It has been slow learning the last few weeks and the fact that you could give me directions and I had the slightest clue to do something with those directions...makes me feel like I am learning so thanks.

    Now that I got it working - any suggestions on how to of made this cleaner? It is much more concise when using while/if statements only.

    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    
    #define IN 1
    #define OUT 0
    
    
    int main()
    {
    	int c, line_count, word_count, character_count, state;
    
    
    	state = OUT;
    	line_count = word_count = character_count = 0;
    
    
    	while((c = getchar()) != EOF && c != 4)
    	{
    		switch (c)
    			{
    		case ' ':
    		case '\t':
    			if(c == ' ' || c == '\t')
    				state = OUT;
    			else if(isalpha(c) && state == OUT)
    			{
    				state = IN;
    			}
    			++word_count;
    			break;
    		case '\n':
    			if(c == '\n')
    				state = OUT;
    			else if(isalpha(c) && state == OUT)
    			{
    				state = IN;
    			}
    			++word_count;
    			++line_count;
    			break;
    		default:
    			if(isalpha(c) && c!=' ' && c != '\n' && c != '\t')
    				++character_count;
    			break;
    		}
    	}
    	
    
    
    	printf("Lines:%d\nWords:%d\nChraracters:%d\n", line_count, word_count, character_count);
    }

  7. #7
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Inside the cases it no longer makes sense to check if 'c' is equal to some character... it's already been established. For example, in case ' ' / case '\t', just do state = OUT. No more checks required. 'state' will never get changed to IN so there is some logic flaw. In the 'default' case you don't need to check if 'c' is ' ' or '\' or '\t' because those cases have been handled before.

  8. #8
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    nonoob - thank you. I tried to condense the code the only problem is that words will increment w/ tab or spaces...


    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    
    #define IN 1
    #define OUT 0
    
    
    int main()
    {
    	int c, line_count, word_count, character_count, state;
    
    
    	state = OUT;
    	line_count = word_count = character_count = 0;
    
    
    	while((c = getchar()) != EOF && c != 4)
    	{
    		switch (c)
    			{														
    		case ' ':													
    		case '\t':
    			state = OUT;
    			++word_count;
    			break;
    		case '\n':
    			state = OUT;
    			++word_count;
    			++line_count;
    			break;
    		default:										
    			++character_count;
    			break;
    		}
    	}
    
    
    	printf("Lines:%d\nWords:%d\nChraracters:%d\n", line_count, word_count, character_count);

  9. #9
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    Tried to modify but \t still increments word. From my code I can understand why, just dont know exactly how to correct.

    Code:
    
    		switch (c)
    			{														
    		case ' ':													
    		case '\t':
    			if(state = OUT && isalpha(c))
    			{
    				state = IN;
    			}
    			++word_count;
    			break;
    		case '\n':
    			++line_count;
    			if(state = OUT && isalpha(c))
    			{
    				state = IN;
    			}
    			++word_count;
    			break;
    		default:										
    			++character_count;
    			break;
    		}

  10. #10
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    Quote Originally Posted by sjmp View Post
    Code:
        while((c = getchar()) != EOF && c != 4)
    I'm really curious why you're breaking out of the loop if c is 4. What is magic about 4? (I think I know what you're trying to do here, but I'll let you explain before I say what I think).

  11. #11
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    need to terminate the program using CNTRL D - ASCII 4? that is what I was trying to do there. It works so long as long as I execute CNTRL D on a new line.

  12. #12
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    Probably making things more of a mess, but trying to get the word count to NOT increment from spaces, new lines, or tabs... tried adding this but still not working

    Code:
    	while((c = getchar()) != EOF && c != 4)
    	{
    		if (c == ' ' || c == '\n' || c == '\t')
    			state = OUT;
    		else if (isalpha(c) && state == OUT)
    		{
    			state = IN;
    		}
    
    
    		switch (c)
    			{														
    		case ' ':													
    		case '\t':
    			if(state == IN)
    				++word_count;
    			break;
    		case '\n':
    			++line_count;
    			if(state == IN)
    				++word_count;
    			break;
    		default:										
    			++character_count;
    			break;
    		}
    	}
    
    
    	printf("Lines:%d\nWords:%d\nChraracters:%d\n", line_count, word_count, character_count);

  13. #13
    Registered User
    Join Date
    Mar 2010
    Posts
    583
    Quote Originally Posted by sjmp View Post
    Tried to modify but \t still increments word. From my code I can understand why, just dont know exactly how to correct.
    I can see where you're trying to go with this I think. I guess that state ==OUT means you're not in a word and state == IN means you're in a word?

    Code:
    		case ' ':													
    		case '\t':
    			if(state = OUT && isalpha(c))
    			{
    First, should the '=' be an '=='? It doesn't matter anyway - you've got to that bit of code because c is space or tab, so isalpha(c) will never be true. Your 'default' case is the right place to check the char is alphanumeric and set "IN". Space/tab would change back to "OUT". Then you can detect each time you finish a word.

  14. #14
    Registered User
    Join Date
    Jul 2012
    Posts
    55
    I was successful in counting words (ignoring tabs, spaces, newlines)
    using:
    Code:
                            if(c == '\n' || c == '\t' || c == ' ')
    				state = OUT;
    			else if(isalpha(c) && state == OUT)
    			{
    				state = IN;
                                    ++word_count;
    			}
    But if I use this in case ' '. '\t'. '\n' - it does not increment. I tried to adding under default - but it did not work.

  15. #15
    Registered User
    Join Date
    May 2012
    Posts
    1,066
    The switch-statement is a replacement for a succession of if-statements that always check the same variable. If you reformat your code like:
    Code:
    if (c == '\n')
        state = OUT;
    else if (c == '\t')
        state = OUT;
    else if (c == ' ')
        state = OUT;
    else if (isalpha(c) && state == OUT)
    {
        state = IN;
        ++word_count;
    }
    is it easier for you to see how you should construct your switch-statement?

    Bye, Andreas

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Question about switch cases
    By cashmerelc in forum C Programming
    Replies: 5
    Last Post: 09-21-2007, 11:57 PM
  2. Replies: 6
    Last Post: 11-10-2005, 01:37 PM
  3. switch cases and timers
    By soranz in forum C++ Programming
    Replies: 5
    Last Post: 10-02-2005, 06:43 PM
  4. switch cases and do while
    By exoillusion in forum C Programming
    Replies: 7
    Last Post: 07-28-2003, 07:18 AM
  5. could someone please explain switch cases?
    By .exe in forum C++ Programming
    Replies: 7
    Last Post: 07-01-2003, 01:42 PM

Tags for this Thread