web-dev-qa-db-ja.com

Cのwhileループ内のswitchステートメント

Whileループ内のswitchステートメントに関する投稿がいくつかありますが、少なくとも私が見た限りでは、Cで実行されていないという事実があります。 C++は、私が知っているブール式を作成できますが、Cでは作成できません。スイッチコントロールを含むwhileループがあります。ただし、スイッチ内にbreakステートメントを書き込むと、ループの最初に戻り、プログラムが永久に実行されます。確かに機能するので、私が使用する関数は無視してください。ネスティングの処理について説明する必要があります。ありがとう!

Here is my main.c:

while(1)
{
    printf("0) Exit\n1) List Tasks\n2) Add Task\n");                                            
    printf("3)Delete Task\n4) Add Task From File\n");                                           
    printf("What would you like to do?\n");
    fgets(buf1, 50, stdin);                                                                     
    p = atoi(buf1);
    switch(p)
    {
          case 0: 
            break;
          case 1: 
            printTaskList(pTaskList);
            break;
          case 2:
            printf("Enter task name: ");
            fgets(buf2,100,stdin);
            printf("Enter task priority: ");
            fgets(buf3,100,stdin);
            printf("Enter task start date: ");
            fgets(buf4,50,stdin);
            pTask = makeTask(buf2,buf4,buf3);
            addTaskToEnd(pTaskList,pTask);
            break;
          case 3:
            printTaskList(pTaskList);
            printf("What task would you like to delete? ");
            fgets(buf6,50,stdin);
            taskNum = atoi(buf6);
            removeTask(pTaskList,taskNum);
            break;
          case 4:
            printf("Enter the filename ");
            fgets(buf7,50,stdin);
            break;
          default:
            printf("ERROR: %d: Incorrect menu option\n", p);
     }
}
6
umarqattan

break;は、最も近い囲んでいるswitchまたはループを終了します。 2つのレベルにジャンプするには、恐ろしいgotoを使用するか、returnが目的のセマンティクスを実現するように再編成する必要があります。

while(1) {
    switch(x) {
    case 0: goto EndWhile;
    }
}
EndWhile: ;

または

void loop() {
    while(1) {
        switch(x) {
        case 0: return;
        }
    }
}
//...
loop();
//...

Cではブール式を完全に使用できます。intを使用するだけです。

int quit = 0;
while(!quit) {
    switch(x) {
    case 0: quit = 1; break;
    }
}

本当に必要な場合は、Cにもブールデータ型があります。

#include <stdbool.h>

bool quit = false;
while(!quit) {
    switch(x) {
    case 0: quit = true; break;
    }
}

そしてもう1つのオプション、完全に正気ではありません。

#include <setjmp.h>

jmp_buf jbuf;
if (!setjmp(jbuf))
    while(1) {
        switch(x) {
        case 0: longjmp(jbuf, 1);
        }
    }
15
luser droog

C++はブール式を作成できますが、これは私が知っていることですが、Cでは作成できません。

ああ?では、ブール式ではない場合、_0 == 0_とは何ですか?タイプboolの変数を参照している場合は、必ず_#include <stdbool.h>_にしてください。

ただし、スイッチ内にbreakステートメントを書き込むと、ループの最初に戻り、プログラムが永久に実行されます。確かに機能するので、私が使用する関数は無視してください。ネスティングの処理について説明する必要があります。ありがとう!

いいえ。ループの最初には戻りません。実行は、switchステートメントの終わりから続行されます(switchesの閉じ中括弧_}_の直後)。あなたの状況では、これは機能的にはループの最初に戻ると同じです。

利用できるオプションがいくつかあります。他の人はあなたのループを制御するために唯一の変数を使用することを提案しています。これは良い考えですが、変数がロジックにすでに存在しているにもかかわらず、new変数を使用することを提案しています。この方法で問題を解決したい場合は、次のことを検討してください。

_do {
    /* ... */
} while (p != 0);
_

または、終了するときにmainからreturnを呼び出すか、他の関数からexit(0);を呼び出します。追加のクリーンアップ/出力コードを実行する場合、これはそれほど役に立ちません。

このシナリオでは、switch制御構造は、if/_else if_/elseブランチのチェーンよりも優れているわけではありません。 if/_else if_/elseブランチを使用する場合は、ループから_break;_をより簡単に外すことができます。実行を他のケースに流したい場合は、switch制御構造を使用します。

別のオプションとして、goto式を使用して、ループから抜け出し、mainの外部のラベルに移動することができます。これは、割り当てエラー後の処理やクリーンアップなど、ループからの出口ポイントが複数ある場合に最適です。

1
autistic

Cでもブール式を使用できます。 1999年のC標準には、stdbool.hヘッダーとデータ型boolがあります。 Visual Studio 2012(!)のような古いC方言では、ブールデータ型がないため、代わりにプレーンintを使用する必要があります。

int keep_looping = 1;
while (keep_looping) {
    ....
    if (....)
        keep_looping = 0;
}

ループを終了することはありません。ブレークはスイッチを壊すだけです。交換する必要があります

while(1)

whileループを終了する必要があることを意味する他の何かで

0
Jensd

あなたの休憩はswitchステートメントを残すだけで、その後続けます

while(1)

永遠にループします。

0
koljaTM

使用exit(0);
終了したい場所。

In this partcular case you have to put the condition in the while loop parameter

whileループから抜け出す他の方法は、returnステートメントを使用することです。ただし、これにより現在の機能も終了します。

適切な解決策は、スイッチ内でgoto label;を使用してから、whileループ外でlabel: statement;を使用することです。

例えば:

while(1){
  switch(x){

   case 0:goto label;

   default:break;
   }
}
label:
printf("out of while loop");
0
abe312