2013-04-20 1 views
5

Es gibt mehrere Postings, die switch-Anweisungen innerhalb von while-Schleifen betreffen, mit Ausnahme der Tatsache, dass keine von ihnen in C erledigt ist, zumindest von dem, was ich gesehen habe. C++ kann boolesche Ausdrücke erstellen, die mir bekannt sind, aber nicht in C. Ich habe eine while-Schleife, die ein switch-Steuerelement enthält. Wenn ich jedoch Break-Anweisungen in meinem Switch schreibe, geht es zurück zum Anfang der Schleife und lässt mein Programm für immer laufen. Ignoriere die Funktionen, die ich verwende, denn sie funktionieren sicher. Ich brauche nur eine Erläuterung zu meinem Umgang mit der Nistgruppe. Vielen Dank!Switch-Anweisung innerhalb der While-Schleife in C

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); 
    } 
} 
+0

Ihre break-Anweisung dient dazu, den Rest der Schalter Klauseln zu überspringen, die Sie in der Zeile nach dem Schalter auskippen bedeutet. Eine gängige Lösung, um den gesamten verschachtelten Bereich zu umgehen, besteht darin, den Code in eine Funktion zu verschieben und return anstelle von break zu verwenden. – 7stud

+0

Identifizieren Sie die Punkte, die Sie aus der while-Schleife innerhalb Ihres switch body herausbrechen wollen, setzen Sie ein Flag, das dies anzeigt, und lassen Sie das 'while (Ausdruck)' das Flag für den break-state auswerten (dh 'while (true)') 'while (stay_in_while)', und '' stay_in_while' 'wird durch den zu brechenden Switch-Code gelöscht. – WhozCraig

+1

Sie haben sich geirrt, C hat boolesche Ausdrücke und einen Datentyp mit einem eingebauten Typ '_Bool' und wenn Sie' 'einschließen Es gibt auch "bool", "false" und "true". –

Antwort

13

break; der nächsten beendet aus umschließenden switch oder Schleife verlassen werden impliziert ersetzen. Um zwei Ebenen zu überspringen, müssen Sie die gefürchtete goto verwenden, oder reorganisieren, damit eine return die gewünschte Semantik erreicht.

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

Oder

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

Sie können völlig ein Booleschen Ausdruck in C. Verwenden Sie einfach einen int verwenden.

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

C hat auch einen booleschen Datentyp, wenn Sie es wirklich wollen.

#include <stdbool.h> 

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

Und noch eine Option, für die total verrückt.

#include <setjmp.h> 

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

Sie machten es wirklich klar! Ich danke dir sehr! Dein Code hat meinen Endlos-Loop-Fehler behoben, genau wie euch alle. Ich merkte, dass ich markieren musste, wo ich die while-Schleife verlassen wollte, also habe ich nur "quit" geändert, um die Negation von "quit" zu werden. – umarqattan

+0

Die Verwendung von 'int' als boolean funktioniert, und ist sehr üblich, aber ich bevorzuge definitiv den stdbool Stil. 'while',' if' und so weiter nehmen alle einen booleschen Ausdruck, und es fühlt sich logisch nicht richtig an, ihnen stattdessen eine Zahl zu geben. 'quit' ist keine Nummer, es ist eine Bedingung. – Gauthier

0

Sie verlassen die Schleife nie. Die Pause wird nur deinen Schalter brechen. Sie sollten

while(1) 

mit etwas anderes, das sollte die while-Schleife

0

Ihre Pause bleibt nur die switch-Anweisung, dann weiter auf der

while(1) 

Schleife für immer.

1

Sie können B-Ausdrücke auch in C haben. Der C-Standard von 1999 hat einen stdbool.h Header und einen Datentyp bool. (!) Bei älteren C Dialekte, wie das in Visual Studio 2012 gibt es keine boolean-Datentyp, so dass Sie stattdessen Ebene Ints verwenden müssen:

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

In C99 gibt es kein 'stdbool.h'? Ich finde das schwer zu glauben ... – Sebivor

+0

@modifiable lvalue: Es gibt sicherlich, im Standard. Und Visual Studio 2012 _still_ hat es nicht. Aber du hast recht, ich hätte nicht sagen sollen, dass es keinen booleschen Typ gibt. Lasst uns um seinetwillen hoffen, dass er nicht bei Microsoft festsitzt. –

+0

Visual Studio 2012 hat keinen C-Compiler. Im Interesse der Bekämpfung aller ", aber es gibt eine 'als C-Code kompilieren Option' Argumente: Es ist nicht ungewöhnlich, dass perfekt gültigen C-Code, der in den letzten zehn Jahren geschrieben wurde nicht mit VS kompilieren. Wenn es keinen C-Code kompilieren kann, dann ist es kein C-Compiler. – Sebivor

1

C++ Booleschen Ausdrücken erstellen können, die ich bin mir dessen bewusst, aber nicht in C.

Oh? Also, was ist 0 == 0, wenn nicht ein boolescher Ausdruck? Wenn Sie sich auf eine Variable vom Typ bool beziehen, stellen Sie sicher, dass Sie #include <stdbool.h>.

Allerdings, wenn ich in meinem Schalter brechen Anweisungen schreiben, geht es zurück an den Anfang der Schleife und macht mein Programm für immer laufen. Ignoriere die Funktionen, die ich benutze, denn sie funktionieren sicher.Ich brauche nur etwas Klärung meiner Handhabung der Verschachtelung. Vielen Dank!

Nein. Es geht nicht zum Anfang der Schleife zurück. Die Ausführung wird vom Ende der Switch-Anweisung (unmittelbar nach der switch es schließenden Klammer, }) fortgesetzt. In Ihrem Fall ist dies funktionell identisch mit , zurück zum Anfang der Schleife.

Ihnen stehen einige Optionen zur Verfügung. Andere schlagen vor, eine einzige Variable zu verwenden, um Ihre Schleife zu steuern. Dies wäre eine gute Idee, aber sie schlagen vor, neue Variablen zu verwenden, trotz der Tatsache, dass die Variable bereits in Ihrer Logik existiert. Wenn Sie Ihr Problem auf diese Weise lösen wollen, betrachten:

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

Alternativ return von Haupt, wenn Sie verlassen möchten, oder exit(0); von anderen Funktionen aufrufen. Dies ist nicht besonders hilfreich, wenn Sie zusätzlichen Bereinigungs-/Ausgabecode ausführen möchten.

In diesem Szenario wird die switch Kontrollstruktur ist nicht wirklich besser als eine Kette von if/else if/else Filialen. Wenn Sie die Verzweigungen if/else if/else verwenden, können Sie break; einfacher aus der Schleife. Ich würde eine switch Kontrollstruktur verwenden, wenn ich möchte, dass die Ausführung in andere Fälle fließt.

Als weitere Option könnten Sie einen goto Ausdruck verwenden, um außerhalb der Schleife zu einem Label außerhalb des Hauptbereichs zu wechseln. Dies wäre am besten, wenn es mehrere mögliche Austrittspunkte aus der Schleife gibt, wie z. B. die Behandlung und Bereinigung nach Zuteilungsfehlern.

0

Verwendung Ausfahrt (0);
wohin Sie möchten.

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

andere Wege aus der while-Schleife kommen könnten zu verwenden sein: return Aussage. Dadurch wird jedoch auch die aktuelle Funktion beendet.

Eine geeignete Lösung könnte darin bestehen, goto label; innerhalb des Schalters zu verwenden und dann label: statement; außerhalb der While-Schleife zu verwenden.

ZB:

while(1){ 
    switch(x){ 

    case 0:goto label; 

    default:break; 
    } 
} 
label: 
printf("out of while loop"); 
+1

sollte in Kommentaren sein. Dies ist eine sehr kleine Antwort IMO. –

+0

Funktioniert das nicht nur, wenn er das gesamte Programm komplett verlassen möchte? Wäre nicht "0 zurückgeben" angemessener, obwohl höchstwahrscheinlich immer noch falsch? –

+0

'return' beendet die Funktion, während 'exit' das gesamte Programm beendet. – abe312