C语言剪刀石头布程序字符串溢出与段错误问题求助
修复剪刀石头布程序的段错误与字符串溢出问题
问题根源
报错__builtin_memcpy writing 9 bytes into a region of size 8明确指向字符串内存溢出:你用来存储电脑选择的Cselection数组大小不足。最长的选择项"scissors"包含8个字符+1个字符串终止符'\0',共9字节,若数组定义为char Cselection[8],strcpy写入时会越界覆盖相邻内存,触发段错误。
修复方案
1. 解决字符串溢出问题
两种可靠方式:
- 改用
const char*直接指向字符串常量,完全避免手动数组大小匹配问题; - 若坚持使用字符数组,将数组大小至少设为
10(预留足够空间容纳最长字符串及终止符)。
2. 优化随机数生成逻辑
原generateRandomNumber若在循环内多次调用,会因srand(time(0))重复初始化导致生成重复随机数,需添加静态变量控制种子仅初始化一次。
修复后完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int generateRandomNumber(int n) { static int is_seeded = 0; // 仅初始化一次随机种子 if (!is_seeded) { srand(time(0)); is_seeded = 1; } return rand() % n; } int main() { char player_name[20]; char player_choice[10]; const char* computer_choice; // 改用指针指向字符串常量,避免溢出 int player_score = 0, computer_score = 0; printf("Enter your name: "); scanf("%s", player_name); for (int round = 0; round < 3; round++) { printf("\nRound %d: Enter rock/paper/scissors: ", round + 1); scanf("%s", player_choice); int c_choice_num = generateRandomNumber(3); // 映射随机数到电脑选择 switch(c_choice_num) { case 0: computer_choice = "rock"; break; case 1: computer_choice = "paper"; break; case 2: computer_choice = "scissors"; break; } printf("Computer chose: %s\n", computer_choice); // 判定单轮胜负 if ((strcmp(player_choice, "rock") == 0 && strcmp(computer_choice, "scissors") == 0) || (strcmp(player_choice, "paper") == 0 && strcmp(computer_choice, "rock") == 0) || (strcmp(player_choice, "scissors") == 0 && strcmp(computer_choice, "paper") == 0)) { player_score++; printf("%s wins this round!\n", player_name); } else if (strcmp(player_choice, computer_choice) == 0) { printf("This round is a tie!\n"); } else { computer_score++; printf("Computer wins this round!\n"); } } // 输出最终结果 printf("\nFinal Score:\n%s: %d | Computer: %d\n", player_name, player_score, computer_score); if (player_score > computer_score) { printf("%s wins the game!\n", player_name); } else if (computer_score > player_score) { printf("Computer wins the game!\n"); } else { printf("The game is a tie!\n"); } return 0; }
关键修复点说明
- 字符串溢出解决:用
const char* computer_choice替代固定大小数组,直接引用只读数据区的字符串常量,彻底消除strcpy导致的内存越界风险; - 随机数稳定性优化:通过静态变量
is_seeded确保随机种子仅在第一次调用generateRandomNumber时初始化,避免循环内生成重复随机数; - 代码可读性提升:变量名改为更清晰的
player_name、computer_choice等,便于维护。
内容的提问来源于stack exchange,提问作者Varun G
相关产品推荐
相关产品推荐

