如何创建一个可以追溯到开始阶段的循环?我的问题在这里:
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;
}
我想让它返回“请,选择一个键”命令,以便使用它的人可以纠正错误。
答案 0 :(得分:123)
使用do / while循环(其他循环类型也可以)。
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);
答案 1 :(得分:37)
构造此循环的另一种方法是在输入有效时使用break
。这避免了必须两次写出退出条件。
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");
}
顺便提一下,让用户输入数字代码来选择音阶是非常差的用户体验。您的程序没有理由不接受“C”并在内部将其转换为“0”;并且,就此而言,它应该接受“a♯”和“b♭”与“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;
}
练习:编写一个程序,在构建时生成scale_codes
表。