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

C语言宾果校验程序触发Signal 11错误的问题排查求助

问题分析与修复

你的程序抛出Signal 11(段错误)的核心原因是指针数组未分配有效内存就直接读写,同时存在多处类型不匹配和逻辑错误,下面逐个拆解问题并给出修复方案:

主要错误点

1. 指针数组误用,未分配内存

你定义的bingoPattern、playerBoard、playerPattern都是char*类型的二维数组,但这些指针并没有指向任何有效的内存空间。比如用fscanf("%d", &bingoPattern[i][j])直接写入指针本身的地址,或者后续用strcmp、strcpy操作这些未初始化的指针,都会导致非法内存访问,触发段错误。

2. 变量类型不匹配

  • char singleNumber; 应该改为 char *singleNumber;:strtok返回的是字符串指针,赋值给char类型会截断地址,导致后续循环中使用非法地址。
  • currentArrayElem = &playerBoard[row][col]; 中,&playerBoard[row][col]是char**类型,而currentArrayElem是char*类型,类型不匹配,直接赋值会导致strcmp访问错误的内存区域。

3. 字符串处理逻辑错误

inputNumString[strlen(inputNumString + 1)] = 32; 这行逻辑完全错误:strlen(inputNumString +1)是从第二个字符开始计算的字符串长度,修改这个位置的字符可能越界,而且你实际想做的应该是去除fgets读取的换行符,而不是随意修改字符。

4. strcpy的非法使用

strcpy(&playerPattern[row][col], "1"); 中,&playerPattern[row][col]是char**类型,不符合strcpy第一个参数需要char*的要求,同时playerPattern的指针未分配内存,写入操作会直接触发段错误。

修复方案(改用int类型存储数字,更简单高效)

因为宾果游戏中的数字都是整数,完全没必要用字符串存储,改用int数组可以避免所有指针和字符串的问题,代码更简洁可靠:

#include <stdio.h>
#include <string.h>
#include <stdlib.h> // 用于atoi函数

int main() {
    // 改用int数组存储,避免指针和字符串的复杂操作
    int bingoPattern[5][5];
    int playerBoard[5][5];
    int playerPattern[5][5]; // 用int标记:1表示已呼叫,0表示未呼叫
    char inputNumString[225];

    // 读取宾果图案
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            fscanf(stdin, "%d", &bingoPattern[i][j]);
        }
    }

    // 读取呼叫的数字字符串,处理换行符
    // 先跳过可能的空行
    while (fgets(inputNumString, 225, stdin) != NULL && inputNumString[0] == '\n');
    // 处理读取到的数字字符串
    int numbersCalled[75];
    int numCalledCount = 0;
    char *token = strtok(inputNumString, " \n");
    while (token != NULL) {
        numbersCalled[numCalledCount++] = atoi(token);
        token = strtok(NULL, " \n");
    }

    // 读取玩家卡片
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            fscanf(stdin, "%d", &playerBoard[i][j]);
        }
    }

    // 初始化playerPattern为0
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            playerPattern[i][j] = 0;
        }
    }

    // 标记已呼叫的数字
    for (int idx = 0; idx < numCalledCount; idx++) {
        int currentNum = numbersCalled[idx];
        for (int row = 0; row < 5; row++) {
            for (int col = 0; col < 5; col++) {
                if (playerBoard[row][col] == currentNum) {
                    playerPattern[row][col] = 1;
                }
            }
        }
    }

    // 宾果校验逻辑:检查行、列、对角线是否全为1
    int bingo = 0;
    // 检查所有行
    for (int row = 0; row < 5; row++) {
        int fullRow = 1;
        for (int col = 0; col < 5; col++) {
            if (playerPattern[row][col] != 1) {
                fullRow = 0;
                break;
            }
        }
        if (fullRow) {
            bingo = 1;
            break;
        }
    }
    // 检查列
    if (!bingo) {
        for (int col = 0; col < 5; col++) {
            int fullCol = 1;
            for (int row = 0; row < 5; row++) {
                if (playerPattern[row][col] != 1) {
                    fullCol = 0;
                    break;
                }
            }
            if (fullCol) {
                bingo = 1;
                break;
            }
        }
    }
    // 检查对角线
    if (!bingo) {
        int diag1 = 1, diag2 = 1;
        for (int i = 0; i < 5; i++) {
            if (playerPattern[i][i] != 1) diag1 = 0;
            if (playerPattern[i][4 - i] != 1) diag2 = 0;
        }
        if (diag1 || diag2) bingo = 1;
    }

    printf(bingo ? "Bingo!\n" : "No Bingo.\n");

    return 0;
}

关键修复说明

  1. 把所有存储数字的数组改为int类型,彻底避免指针和字符串操作的内存问题。
  2. 修正了读取呼叫数字的逻辑,正确处理换行符,用atoi把字符串转为整数。
  3. 标记已呼叫数字时直接用整数比较,替代原来的strcmp,逻辑更清晰。
  4. 添加了完整的宾果校验逻辑(行、列、对角线),完成程序的核心功能。

内容的提问来源于stack exchange,提问作者anthonyvn

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:25:27