Reputation: 28858
I'm reading through some books about C. I found the following example to switch case in C, which I try to understand ...
/* caps.c */
#include <stdio.h>
#include <ctype.h>
#define SEEK 0
#define REPLACE 1
int main(void)
{
int ch, state = SEEK;
while(( ch = getchar() ) != EOF )
{
switch( state )
{
case REPLACE:
switch( ch )
{
case ' ': //leaving case empty will go to default ???
case '\t':
case '\n': state = SEEK;
break;
default: ch = tolower( ch );
break;
}
break;
case SEEK:
switch( ch )
{
case ' ':
case '\t':
case '\n': break;
default: ch = toupper( ch );
state = REPLACE;
break;
}
}
putchar( ch );
}
return 0;
}
It is pretty clear to me that the mode SEEK, and then letters are Capitalized, and then mode is set to REPLACE, then letters are converted to lower. But why empty spaces trigger again SEEK mode ? Is this really the case in my comment ?
Upvotes: 4
Views: 30569
Reputation: 11912
This is so-called fall-through behaviour of C switch
operator. If you don't have a break
at the end of a case
region, control passes along to the next case
label.
For example, the following snippet
int x = 5;
switch( x ) {
case 5:
printf( "x is five!\n" );
case 2:
printf( "x is two!\n" );
break;
default:
printf( "I don't know about x\n" );
}
outputs
x is five!
x is two!
Be careful.
Upvotes: 20
Reputation: 3307
case ' ': //leaving case empty will go to default ???
First I want to make clear that , if you write case ' ': , you are not leaving the case empty. You are actually writing a case 32: , since ASCII value of space is 32.
In general, whenever you write 'a',or'b' or any charecter constant, there will be an implicit conversion of the charecter specified to its corresponding ASCII value.
Proof:
The prototype of isspace() is,
int isspace ( int c );
And not as,
int isspace ( char c );
Comment out the case ' ': statement. Then you will find answer yourself. If I comment out case ' ': ,
Then on input, hello world the output will be, Hello world <not expected> instead of Hello World (needed output).
Upvotes: 0
Reputation: 881453
Leaving a case empty does not go to default, it drops through to the next case.
So the piece of code:
case ' ': // leaving case empty will drop through to `\t` and then `\n`.
case '\t':
case '\n': state = SEEK;
break;
default: ch = tolower( ch );
break;
will set the state to SEEK for spaces, tabs and newlines, otherwise it will lower-case the character.
What you have here is a little finite state machine with two states.
In SEEK mode, it will skip over all the white space (tabs, spaces and newlines) and, when it finds a different character, it will upper-case it and switch to REPLACE mode.
In REPLACE mode, it will lower-case all characters until it finds white space then switch to SEEK mode.
Hence text like:
PaxDiablo is a REALLY cool guy
will become:
Paxdiablo Is A Really Cool Guy
Upvotes: 4
Reputation: 13382
In this case what will happen is that the switch will enter at the appropriate case
statment, so if ch=' '
at the top then run until it hits a break
.
This means that if ch
is one of ' ','\t'
or '\n'
then state
will be set to SEEK
.
Upvotes: 4