C语言猜色程序输入时触发Segmentation fault (core dumped)的修复方法
C猜色游戏段错误修复方案
问题根源分析
程序触发段错误的核心原因是缓冲区溢出,次要问题包括随机数生成器初始化位置不当以及缺少程序入口函数。
具体修复点及代码修正
以下是完整的修复后代码:
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> void colour(char guess[100]) { char ans; int i; char *colours[] = {"RED", "BLUE", "GREEN", "YELLOW", "BLACK"}; printf("Welcome to the guessing game!!\n"); play_again: printf("Do you want to play?? Enter Y/n: \n"); // 修复:使用%c读取单个字符,避免缓冲区溢出 scanf(" %c", &ans); // 支持大小写Y的输入 while (ans == 'Y' || ans == 'y') { // 每局游戏只随机选择一次颜色 char *random_colour = colours[rand() % 5]; printf("I have 5 colours: RED, BLUE, GREEN, YELLOW, BLACK.\n"); printf("I have chosen one of the colours, can you guess it??\n"); for (i = 3; i > 0; i--) { printf("You have %d tr%s.\n", i, i == 1 ? "y" : "ies"); printf("Enter your guess: \n"); // 读取最多99个字符,适配100字节的缓冲区 scanf(" %99s", guess); int result = strcmp(guess, random_colour); if (result == 0) { printf("You guessed it, WELL DONE!! The colour is %s.\n", random_colour); goto play_again; } else { printf("Not the correct colour, %s.\n", i == 1 ? "game over" : "guess again"); } } printf("Sorry, you lose!! The colour is %s.\n", random_colour); goto play_again; } printf("Thank you, Goodbye!!\n"); } int main() { // 程序启动时仅初始化一次随机数生成器 srand((unsigned int)time(NULL)); char guess_buffer[100]; colour(guess_buffer); return 0; }
修复细节说明
修复缓冲区溢出:
原代码中scanf(" %s", &ans)使用%s格式符读取单个字符变量ans,会导致输入的字符加上终止符\0溢出单字节的ans,破坏栈内存,进而引发段错误。改为scanf(" %c", &ans)后,仅读取单个字符,彻底避免溢出。调整随机数生成器初始化位置:
原代码在循环内重复调用srand,若用户快速重启游戏,time()返回值可能相同,导致随机颜色重复。将srand((unsigned int)time(NULL))移至main函数,确保程序启动时仅初始化一次,保证随机序列的唯一性。补充程序入口函数:
原代码缺少main函数,这会导致编译错误。修复后的代码添加了main函数,作为程序的入口点,并正确传递猜测缓冲区给colour函数。输入灵活性优化(可选):
新增对小写y的支持,提升用户输入体验。
内容的提问来源于stack exchange,提问作者B Fitz
相关产品推荐
相关产品推荐

