C中的空开关盒

时间:2011-08-31 09:16:09

标签: c switch-statement

我正在读一些关于C.的书。我发现了以下example to switch case in C, 我试图理解......

/* 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;
   }

我很清楚模式SEEK,然后字母是大写,然后模式设置为REPLACE,然后字母转换为更低。但为什么空格会再次触发SEEK模式?这是我的评论中的情况吗?

4 个答案:

答案 0 :(得分:12)

这是C switch运算符的所谓直通行为。如果您在break区域末尾没有case,则控件会传递到下一个case标签。

例如,以下代码段

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" );
}

输出

x is five!
x is two!

小心。

答案 1 :(得分:4)

在这种情况下,将会发生的情况是,交换机将在相应的case个参数中输入,因此如果顶部的ch=' '一直运行,直到它到达break

这意味着如果ch' ','\t''\n'之一,则state将设置为SEEK

答案 2 :(得分:3)

如果案例为空,将变为默认值,它会进入下一个案例。

所以这段代码:

case ' ':    // leaving case empty will drop through to `\t` and then `\n`.
case '\t':
case '\n':   state = SEEK;
             break;
default:     ch = tolower( ch );
             break;

会将状态设置为SEEK以获取空格,制表符和换行符,否则会将该字符设置为小写。

这里有一个有两种状态的有限状态机。

  • 在SEEK模式下,它将跳过所有空白区域(制表符,空格和换行符),当它找到不同的字符时,它会大写它并切换到REPLACE模式。

  • 在REPLACE模式下,它将小写所有字符,直到找到空格,然后切换到SEEK模式。

因此文字如下:

PaxDiablo is a REALLY cool guy

将成为:

Paxdiablo Is A Really Cool Guy

答案 3 :(得分:1)

case ' ':    //leaving case empty will go to default ???

首先,我要说明一点, 如果你写 case'':,你不会把案子留空。实际上你正在写一个 case 32:,因为空间的ASCII值是32。

一般来说, 无论何时编写'a','b'或任何charecter常量,都会将指定的charecter隐式转换为相应的ASCII值。

Proof: 
 The prototype of isspace() is,
 int isspace ( int c );
 And not as,
 int isspace ( char c );

评论案例'':陈述。然后你会自己找到答案。如果我注释掉案例'':,

 Then on input,
    hello world
    the output will be,
    Hello world   <not expected>
    instead of 
    Hello World  (needed output).