为什么第二个 getchar() 调用总是触发我的开关的默认情况?

Why does the second getchar() call always trigger my switch's default case?

我正在尝试使用嵌套的 switch 语句编写一个菜单,供用户选择一些选项。第一个开关工作正常而嵌套的开关没有。 在嵌套开关中,我总是以 default 选项结束,用户无法选择。

似乎变量 d 保持为 NULL,这就是使开关以默认选项结束的原因。是什么阻止了用户能够键入一个字符,又阻止了代码将值赋给 d

#include<mysql.h>
#include<stdio.h>
#include<stdlib.h>

/* function declaration */
int connection_func();
int main() {  
    /*make connection to sql server*/
    int connection_return = connection_func();
    printf("%d",connection_return);

       char c,d;
       printf("\n Choose one of the following options: \n");
    printf("1- DB maintenance \n");
    printf("2- Weekly schedule creation \n");
    c= getchar();
    switch(c) {
            case '1':
                    // DB maintenance
                    printf("\n DB maintenance options:: \n");
                    printf("1- ADD data to existing table \n");
                    printf("2- DELETE data from existing table \n");
                    printf("3- DISPLAY all data inside a table \n");
                    printf("4- DROP table (root only) \n");
                    d = getchar();
                    switch(d) {
                            case 'A':
                            //  User want to ADD data to the database
                            break;
                            case 'B':
                            // User want to DELETE data from database
                            break;
                            case 'C':
                            // User want to Display the tbl data
                            break;
                            case 'D':
                            // User want to DROP tables
                            break;
                            default:
                            printf("That is not a proper selection \n");
                            break;
   }
                    break;

            case '2':
                    // Weekly schedule creation
                    break;
            default:
                    printf("That is not a proper selection. \n");
                    break;
    }

return(0);
}

int connection_func() {
    MYSQL           *conn;
    MYSQL_RES       *res;
    MYSQL_ROW       row;
    char *server  = "localhost";
    char *user     = "root";
    char *password = "mypassword";
    char *database = "sc" ;

    conn = mysql_init(NULL);
    /* Connect to database */
    if ( !mysql_real_connect(conn, server, user, password, database, 0, NULL , 0)) {
            fprintf(stderr, "%s\n", mysql_error(conn));
            return(1);
    }
return(0);
}

编译没有错误。终端的输出:

root@kali:# ./sc
0
 Choose one of the following options: 
1- DB maintenance
2- Weekly schedule creation 
1
(null) -d       (**** - the value of d variable ***) 
 DB maintenance options:: 
1- ADD data to existing table 
2- DELETE data from existing table 
3- DISPLAY all data inside a table 
4- DROP table (root only) 
That is not a proper selection 

请注意,您甚至没有机会说 AB

1 后按 Enter1 进入 cd = getchar() 导致 d 有换行代码。

当您输入“1”时,您实际上向程序提供了两个字符,一个“1”,然后是输入(在标准输入中显示为换行符)。 换行符随后由对 d = getchar() 的第二次调用返回。 (您可以输入两个选项以查看您的程序是否有效:例如 12,然后按 ENTER)。

如果你想跳过白色 space,比如换行符、制表符和 space,我建议使用 scanf(" %c", &d)。初始 space 告诉 scanf 在转换单个字符之前跳过任意数量的白色 space。一定要勾选scanf returns 1,表示成功转换item为scan。

插入“1”并单击回车后,stdin 流中有“1\n”, 然后调用 getchar() 一次,“1”已从标准输入中删除。

然后,对 getchar() 的下一次调用不会提示用户,因为标准输入流中已经有数据 - 换行符“\n”。

尝试使用

while((d = getchar()) != '\n' && d != EOF);

将无用的数据分出直到换行符,通常它只是 '\n' 字符,因此您甚至可以使用 execute 只再调用一次 getchar() 来从流中删除换行符.

此外,正如其他评论中提到的,我会考虑 fgets