You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:我的程序为何会跳过gets()函数?

问题根源与解决方案

嘿,这个坑我当初学C的时候也踩过!你遇到的问题核心在于输入缓冲区里残留的换行符:

当你用scanf("%d", &escolha);选择菜单选项后,你按下的回车键(换行符\n)并没有被scanf读取——它只拿走了整数部分,剩下的换行符就留在了输入缓冲区里。等后续调用gets()时,它会直接读取这个换行符,觉得你输入了一个空行,所以看起来像是“跳过”了输入步骤。

而scanf读字符串时(比如scanf("%s", ...))会自动跳过开头的空白字符(包括换行),但它只能读到第一个空格就停止,这就是为什么你没法用它读取全名的原因。

解决方案1:手动清空缓冲区里的换行符

在scanf读取完整数后,用getchar()把残留的换行符吃掉:

int menu(){
    int escolha;
    puts("1 - Definir dados da conta.");
    puts("2 - Depositar Dinheiro.");
    puts("3 - Levantar Dinheiro.");
    puts("4 - Sair.");
    printf("Escolha a sua operação: ");
    scanf("%d", &escolha);
    // 吃掉残留的换行符
    getchar();
    return escolha;
}

不过要注意,如果用户输入整数后还输入了空格再回车,这个方法可能不够彻底,需要循环调用getchar()直到读到换行符,但对于你的场景,简单的getchar()已经够用。

解决方案2:用fgets()替代不安全的gets()

更推荐这个方案——因为gets()已经被C标准废弃了(从C11开始),它不检查缓冲区长度,很容易导致缓冲区溢出,非常不安全。

fgets()可以指定读取的最大长度,还能正确处理输入缓冲区的问题。修改你的defDadosDeConta()函数:

#include <string.h> // 需要引入strcspn的头文件

void defDadosDeConta(){ // 这里要加上返回类型void
    printf("Insira o seu nome: ");
    // 读取最多49个字符(留一个位置给结束符\0)
    fgets(conta1.nomeDoCliente, sizeof(conta1.nomeDoCliente), stdin);
    // 去掉fgets读取到的换行符(如果存在)
    conta1.nomeDoCliente[strcspn(conta1.nomeDoCliente, "\n")] = '\0';
    puts("Dados de conta guardados com sucesso!");
}

同时,菜单里的scanf之后还是需要用getchar()吃掉换行,或者也可以用fgets()配合sscanf()来读取菜单选项,彻底避免缓冲区残留问题:

int menu(){
    int escolha;
    char input[10];
    puts("1 - Definir dados da conta.");
    puts("2 - Depositar Dinheiro.");
    puts("3 - Levantar Dinheiro.");
    puts("4 - Sair.");
    printf("Escolha a sua operação: ");
    fgets(input, sizeof(input), stdin);
    sscanf(input, "%d", &escolha);
    return escolha;
}

额外小提示

你的defDadosDeConta()函数没有声明返回类型,这在C里是不规范的(默认会被当成返回int,但实际上你不需要返回值),所以最好加上void声明。

内容的提问来源于stack exchange,提问作者Javabeginner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:49:48