如果为false则强制函数返回

时间:2014-01-11 22:35:45

标签: c

如何创建一个可以追溯到开始阶段的循环?我的问题在这里:

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;
    }

我想让它返回“请,选择一个键”命令,以便使用它的人可以纠正错误。

2 个答案:

答案 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表。