求助:我的程序为何会跳过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

