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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 04:10:33