#include <stdio.h>
int main()
{
repeat:
printf("choose an option: \n1:Draw\n2:Even or Odd:\n3:Text type\n4:How to Dec\n5:Base to Dec:\n6:Count to Bits\n0:Exit\n");
int x;
scanf("%d", &x);
if (x > 6)
printf("Wrong option!\n");
goto repeat;
if (x == 1)
printf("Drawing");
if (x == 0)
printf("we are out!\n");
return 0;
}
I am using an online complier.
The end result I want to see is a simple menu that asks the user for input number and executes a code according to the number and then goes to the starting point and prints the menu again. (That's why I chose goto. If you have other solution that restarts the main program after an execution please tell me.)
The problem I encountered is that no matter the number I input, it outputs the menu again without the messages or without exiting (when I input 0).
C is not indentation dependent. Just change
if (x > 6)
printf("Wrong option!\n");
goto repeat;
to
if (x > 6) {
printf("Wrong option!\n");
goto repeat;
}
You can only omit the braces for single statements.
But I would strongly advice against using goto
like this. goto
has it's uses, but this is not one of them. You could rewrite your code like this:
int main()
{
while(1) {
printf("choose an option: \n1:Draw\n2:Even or Odd:\n3:Text type\n4:How to Dec\n5:Base to Dec:\n6:Count to Bits\n0:Exit\n");
int x;
scanf("%d", &x);
if (x > 6) {
printf("Wrong option!\n");
}
if (x == 1) {
printf("Drawing");
break;
}
if (x == 0) {
printf("we are out!\n");
break;
}
}
}
It's not how I would have written it. I changed to a while loop with as few changes as possible. I would have done something like this:
int x = 6;
while(x == 6) {
printf("choose an option: \n1:Draw\n2:Even or Odd:\n3:Text type\n4:How to Dec\n5:Base to Dec:\n6:Count to Bits\n0:Exit\n");
// Always check scanf for errors
if(scanf("%d", &x) != 1) { perror("Input error"); exit(1); }
switch(x) {
case 1: printf("Drawing"); break;
case 0: printf("we are out!\n"); break;
default: printf("Wrong option!\n");
}
}
There are only two cases where I would ever consider using goto
:
To break out of a nested loop
To clean up allocated resources in a function on failure
Example of breaking out of nested loop:
while(1) {
while(1) {
if(<condition>) goto END;
}
}
END:
Example of cleanup:
void foo() {
char *p = malloc(1);
if(!p) goto END;
char *q = malloc(1);
if(!q) goto P;
// Do stuff
free(q);
P:
free(p);
END:
}
Note that the cleanup example is not very good, since you can safely free a NULL pointer, which malloc
returns on failure. An example with fopen
would be more appropriate. But it demonstrates the general principle. That you do the cleanup in reverse order and jump to the appropriate place in case of failure.
And whatever you do, NEVER jump backwards with goto. Only jump forwards. Or at least I have never seen a case where a backwards jump would be motivated.
In languages that support exceptions, you would typically use exceptions for both of these cases. First example would be something like this pseudo:
try {
while(1) {
while(1) {
if(<condition>) throw MyException;
}
}
} catch MyException {}