web-dev-qa-db-fra.com

Passer d'un cas à un autre par défaut dans l'instruction switch

switch(ch){
          case 'a':
                 //do something, condition does not match so go to default case
                 //don't break in here, and don't allow fall through to other cases.
          case 'b':
                 //..
          case 'c':
                 //..
          case '_':
                 //...
          default:
                 //
                 break;
}

Dans une instruction switch comme ci-dessus, je saisis la casse 'a', je ne casse que si la condition à l'intérieur est remplie, sinon je veux passer à la casse par défaut. Y a-t-il une autre façon de faire cela plutôt que des labels ou des gotos?

17
thetux4

goto pour la victoire

switch (ch) {
    case 'a':
        if (1) goto LINE96532;
        break;
    case 'b':
        if (1) goto LINE96532;
        break;
LINE96532:
    default:
        //
        break;
}
21
pmg

Il suffit de réorganiser les cas pour que ce cas soit le dernier:

switch(ch){
          case 'b':
                 //..
          case 'c':
                 //..
          case '_':
                 //...
          case 'a':
                 //do something, condition does not match so go to default case
                 if (condition)
                     break;
                 //don't break in here, and don't allow fall through to other cases.
          default:
                 //
                 break;
}
7
Diego Sevilla

Si la condition ne dépend pas des cas, pourquoi la mettre à l'intérieur?

if (!condition){
  // do default
}else{
  switch(ch){
    case 'a':
      // do a
      break;
    ...
  }
}
5
mouviciel

Refactoriser votre code:

int test_char(char ch)
{
  switch(ch) {
    case 'a': if (condition) return 0; break;
    case 'b': // ...
    default: return -1;
  }

  return 1;
}

... 
// defaults processing switch
switch(test_char(ch)) {
  case 0: break; // condition met
  case 1: // default processing
  default: // case not handled by test_char
}

Cela ajoute également l’avantage d’être flexible pour tester plusieurs classes de traitement par défaut. Supposons que vous avez un groupe de caractères [c, d, e, f] qui partagent une logique commune. Renvoyez simplement 2 de test_char () pour ces cas (éventuellement après le test de certaines conditions) et ajoutez un gestionnaire cas 2: à l'instruction de traitement par défaut.

5
Kaos

Je ne suis pas sûr que ce soit la meilleure réponse, mais la voici:

Si vous ne voulez absolument pas utiliser les étiquettes et que vous voulez conserver les cas dans leur ordre actuel, vous pouvez continuer après le cas 'a' et ensuite vérifier si cas suivant, exécution de l'instruction uniquement si la condition est vraie:

switch(ch){
    case 'a':
        // do something
    case 'b':
    if(ch != 'a') {
        //do something
    }
    //repeat for each subsequent case
    default:
        //do something
    break;
}

Ce n'est probablement pas le moyen le plus efficace de résoudre votre problème, mais il devrait vous permettre d'atteindre vos objectifs.

1
Andrew

J'espère que ma solution répond à votre question. Laissez simplement les cas suivre jusqu'au bout (en commençant par le cas correspondant), mais utilisez une condition pour désactiver le traitement des cas suivants. 

typedef enum boolean
{
    FALSE = 0, TRUE = 1
} bool;

void pstuff(char input)
{
    bool _skip = FALSE; 
    switch(input)
    {
        case 'a':
            printf("Case a.");
            _skip = TRUE; 
        case 'b': 
            if(!_skip)
            {
                printf("Case b.");
                _skip = TRUE;
            }
        case 'c':       
            if(!_skip)
            {
                printf("Case c.");
                _skip = TRUE; 
            }
        //...
        default: 
            printf("Done!\n"); //Always gets printed.

    }   
}
0
Minh Tran

Si vous devez avoir les instructions switch en premier parce que la condition recherchée dépend du cas (ou si le cas doit être évalué avant de pouvoir vérifier la condition), définissez simplement un indicateur dans vos cas switch Si le drapeau est défini, effectuez une opération par défaut. Par exemple:

int default_true = 0;
switch (case_value)
{
    case 'a': /* if the condition is true, set the default_true flag */

    case 'b': /* if the condition is true, set the default_true flag */

    //...

    default: default_flag = 1; // set the default_true flag to true
}

if (default_flag)
{
    //place your "default" code here rather than inside the switch statement
    //this prevents code reduplication
}
0
Jason

Voici ce que j'ai fait:

char ucResult = 1;
switch(ch){
      case 'a':
          if(ucResult){
             // do something
             if(error) ucResult = 0;
          }
      case 'b':
          if(ucResult){
             // do something
             if(error) ucResult = 0;
          }
      case 'c':
          if(ucResult){
             // do something
             if(error) ucResult = 0;
          }
      case '_':
          if(ucResult){
             // do something
             if(error) ucResult = 0;
          }
      default:
             //
             break;
}

Avec cette structure, vous pouvez basculer entre les cas précédents et les cas par défaut. Pratique pour rompre les boucles externes aussi.

0
Taha Paksu