调用startgame()后如何让gets(name)函数正常工作?
问题分析与解决方案
你的判断完全正确,问题根源就是scanf("%s")读取输入后残留的换行符。当你输入"start"并按下回车时,scanf只会读取"start"字符串本身,换行符\n会留在输入缓冲区中。后续调用gets(name)时,它会直接读取这个换行符并判定为空输入,导致跳过了你的实际输入操作。
另外必须强调:gets()函数已被C标准彻底废弃,它没有任何缓冲区边界检查,存在严重的溢出风险,绝对不能在代码中使用。
解决方案1:手动清理输入缓冲区
在startgame()的scanf执行后,主动清空缓冲区中剩余的所有字符直到遇到换行符:
int startgame(){ char decision [100]; do{ printf("Welcome to 'A Week in Basilisk'. Type 'start' to continue.\n"); scanf("%s", decision); // 清理缓冲区残留的换行符及其他字符 while(getchar() != '\n'); if(strcmp(decision, "start") == 0){ printf("starting...\n"); } else if (strcmp(decision, "quit") == 0){ printf("quiting...\n"); exit(0); } } while(strcmp(decision, "start") != 0); return 0; }
同时将main()中的gets(name)替换为安全的fgets,并处理掉读取到的换行符:
fgets(name, sizeof(name), stdin); // 截断换行符,避免影响后续字符串处理 name[strcspn(name, "\n")] = '\0';
解决方案2:统一使用fgets处理输入
彻底替换scanf为fgets,从根源避免缓冲区残留问题,同时保证输入安全性:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> int startgame(); int main(){ char name[256]; int dexterity, endurance, strength, intelligence, health = 0; int endingtokens = 0; startgame(); printf("请输入你的名字:"); fgets(name, sizeof(name), stdin); name[strcspn(name, "\n")] = '\0'; // 去除换行符 printf("你的名字是:%s\n", name); return 0; } int startgame(){ char decision [100]; do{ printf("Welcome to 'A Week in Basilisk'. Type 'start' to continue.\n"); fgets(decision, sizeof(decision), stdin); // 去除fgets读取到的换行符 decision[strcspn(decision, "\n")] = '\0'; if(strcmp(decision, "start") == 0){ printf("starting...\n"); } else if (strcmp(decision, "quit") == 0){ printf("quiting...\n"); exit(0); } } while(strcmp(decision, "start") != 0); return 0; }
关键注意事项
strcspn(name, "\n")会返回字符串中第一个换行符的下标,用它可以精准截断换行符,避免后续逻辑出错。- 无论何时都不要使用
gets(),它是C语言历史上最危险的函数之一。 - 使用
fgets时必须指定最大读取长度(一般用sizeof获取数组长度),这是保证缓冲区安全的核心。
内容的提问来源于stack exchange,提问作者Jake Delso
相关产品推荐
相关产品推荐

