Obligando a una función a regresar si es falso

¿Cómo puedo crear un bucle que se remonta a la etapa inicial? Mi problema está aquí:

int main(void) { midi_start(); program_change(1, 1); program_change(2, 1); t=400; printf("Choose a scale and write the code of it:\n "); printf("C:0\n "); printf("C#:1\n "); printf("D:2\n "); printf("D#:3\n "); printf("E:4\n "); printf("F:5\n "); printf("F#:6\n "); printf("G:7\n "); printf("G#:8\n "); printf("A:9\n "); printf("A#:10\n "); printf("B:11\n "); printf("The chosen key is:\n"); scanf("%d",&kk); k = kk + 60; if (kk >= 12) { printf("Go back to the start."); return main; } 

Quiero hacer que vuelva al comando “Por favor, elija una tecla” para que la persona que usa esto pueda corregir el error.

Utilice un bucle do / while (otros tipos de bucles también funcionarían).

 do { printf("The chosen key is:\n"); scanf("%d",&kk); k = kk + 60; if (kk >= 12) printf("Go back to the start."); } while (kk >= 12); 

Otra forma de estructurar este bucle es con una break cuando la entrada es válida. Esto evita tener que escribir la condición de salida dos veces.

 for (;;) { puts("Enter scale: C, C#, D, D#, E, F, F#, G, G#, A, A#, B"); kk = get_scale(); if (kk == -2) { perror("stdin"); exit(1); } if (kk >= 0 && kk <= 11) break; puts("?Redo from start"); } 

Incidentalmente, hacer que el usuario ingrese un código numérico para elegir una escala musical es un UX extremadamente pobre. No hay razón para que su progtwig no pueda aceptar "C" y convertirlo a "0" internamente; y, para el caso, debería aceptar "a♯" y "b ♭" como lo mismo que "A #".

 struct scale_code { unsigned short code; const char scale[6]; }; /* This table is sorted UTF8betically by the 'scale' field to permit binary search. */ static const struct scale_code scale_codes[] = { { 9, "A" }, { 10, "A#" }, { 8, "A♭" }, { 10, "A♯" }, { 11, "B" }, { 10, "B♭" }, { 0, "C" }, // ... { 7, "g" }, { 8, "g#" }, { 6, "g♭" }, { 8, "g♯" }, }; static int scale_code_compar(const void *k, const void *v) { return strcmp((const char *)k, ((const struct scale_code *)v)->scale); } static int get_scale(void) { static char *lineptr = 0; static size_t linealloc = 0; ssize_t count = getline(&lineptr, &linealloc, stdin); if (count <= 0) return -2; /* read error */ /* Valid input can be no fewer than 2 UTF-8 bytes, and no more than 6, and should end with a \n. */ if (count < 2 || count > 6) return -1; if (lineptr[count-1] != '\n') return -1; /* chomp */ lineptr[count-1] = '\0'; const struct scale_code *entry = bsearch(lineptr, scale_codes, sizeof(scale_codes)/sizeof(scale_code), sizeof(scale_code), scale_code_compar); if (!entry) return -1; return entry->code; } 

Ejercicio: escriba un progtwig para generar la tabla scale_codes en el momento de la comstackción.