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

C语言二维数组输出异常求助:学生信息存储后打印结果不符

问题根源与修复方案

嘿,你的问题出在指针数组没有分配有效内存,加上一些小的参数和循环错误,导致内存越界和乱码输出。咱们一步步拆解:

核心错误分析

  1. 野指针问题:你定义的char *Grades[1][6]是一个指针数组,但里面的每个指针都是「野指针」——它们没有指向任何可以存储字符串的内存空间。当你用scanf(" %s",&Grades[line][column]);时,实际上是把输入的字符串直接写到了指针本身的内存位置(而不是指针应该指向的缓冲区),这会覆盖相邻指针的内容,导致打印出拼接的乱码(比如BigFirstBigLastN18就是名字字符串覆盖了后面的指针内存)。
  2. scanf参数错误:%s格式符需要接收一个char*类型的参数,但你传了&Grades[line][column],这是char**类型,类型不匹配,而且直接操作指针的内存本身就是危险行为。
  3. 循环越界:你只存储了6个元素,但循环写了p<7,会访问不存在的第7个元素,导致未定义行为。

修复方案1:使用固定大小的二维字符数组(简单直接)

这种方式适合提前知道字符串最大长度的场景,直接为每个元素分配足够的缓冲区:

#include <stdio.h>
// 定义二维字符数组:1行6列,每个元素最多存50个字符(含结束符'\0')
char Grades[1][6][50];
int line = 0;
int column = 0;

int main(void) {
    printf("Input Firstname \n");
    // 用%49s限制输入长度,防止缓冲区溢出(留1位给结束符)
    scanf(" %49s", Grades[line][column]);
    column += 1;

    printf("Input Lastname \n");
    scanf(" %49s", Grades[line][column]);
    column += 1;

    printf("Input age ");
    scanf(" %49s", Grades[line][column]);
    column += 1;

    printf("Input Math Grade \n");
    scanf(" %49s", Grades[line][column]);
    column += 1;

    printf("Input Physics Grade \n");
    scanf(" %49s", Grades[line][column]);
    column += 1;

    printf("Input Average Between the two \n");
    scanf(" %49s", Grades[line][column]);
    column += 1;

    // 循环次数改为6,匹配存储的元素数量
    int p;
    for (p = 0; p < 6; p++) {
        printf("%s\n", Grades[0][p]);
    }
    return 0;
}

修改点说明:

  • 把指针数组改成char Grades[1][6][50],每个元素都是现成的字符缓冲区
  • 去掉scanf参数里的&,直接传Grades[line][column](它本身就是char*类型)
  • 用%49s限制输入长度,避免缓冲区溢出
  • 循环次数从7改为6,防止越界访问

修复方案2:动态分配内存(灵活适配任意字符串长度)

如果不确定输入字符串的长度,可以用动态内存分配,避免浪费空间:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *Grades[1][6];
int line = 0;
int column = 0;

int main(void) {
    char buffer[100]; // 临时缓冲区存输入内容

    printf("Input Firstname \n");
    scanf(" %99s", buffer);
    // 按输入字符串的实际长度分配内存(+1是为了存储结束符'\0')
    Grades[line][column] = malloc(strlen(buffer) + 1);
    if (Grades[line][column] == NULL) {
        perror("Failed to allocate memory");
        return 1;
    }
    strcpy(Grades[line][column], buffer);
    column += 1;

    printf("Input Lastname \n");
    scanf(" %99s", buffer);
    Grades[line][column] = malloc(strlen(buffer) + 1);
    if (Grades[line][column] == NULL) {
        perror("Failed to allocate memory");
        return 1;
    }
    strcpy(Grades[line][column], buffer);
    column += 1;

    printf("Input age ");
    scanf(" %99s", buffer);
    Grades[line][column] = malloc(strlen(buffer) + 1);
    if (Grades[line][column] == NULL) {
        perror("Failed to allocate memory");
        return 1;
    }
    strcpy(Grades[line][column], buffer);
    column += 1;

    printf("Input Math Grade \n");
    scanf(" %99s", buffer);
    Grades[line][column] = malloc(strlen(buffer) + 1);
    if (Grades[line][column] == NULL) {
        perror("Failed to allocate memory");
        return 1;
    }
    strcpy(Grades[line][column], buffer);
    column += 1;

    printf("Input Physics Grade \n");
    scanf(" %99s", buffer);
    Grades[line][column] = malloc(strlen(buffer) + 1);
    if (Grades[line][column] == NULL) {
        perror("Failed to allocate memory");
        return 1;
    }
    strcpy(Grades[line][column], buffer);
    column += 1;

    printf("Input Average Between the two \n");
    scanf(" %99s", buffer);
    Grades[line][column] = malloc(strlen(buffer) + 1);
    if (Grades[line][column] == NULL) {
        perror("Failed to allocate memory");
        return 1;
    }
    strcpy(Grades[line][column], buffer);
    column += 1;

    // 打印并释放内存(避免内存泄漏)
    int p;
    for (p = 0; p < 6; p++) {
        printf("%s\n", Grades[0][p]);
        free(Grades[0][p]);
    }
    return 0;
}

修改点说明:

  • 用临时缓冲区buffer先接收输入,再根据实际长度动态分配内存
  • 每次malloc后检查是否成功,避免空指针错误
  • 用strcpy把缓冲区内容复制到分配的内存中
  • 最后记得用free释放内存,防止内存泄漏

额外优化:用结构体存储学生信息(更符合逻辑)

其实年龄、成绩都是数值类型,用字符串存储不太合理,建议用结构体把不同类型的学生信息组织起来,代码更清晰:

#include <stdio.h>

// 定义学生结构体,包含所有需要的字段
typedef struct {
    char firstname[50];
    char lastname[50];
    int age;
    int math_grade;
    int physics_grade;
    float average;
} Student;

Student students[1]; // 存储1个学生的信息

int main(void) {
    printf("Input Firstname \n");
    scanf(" %49s", students[0].firstname);

    printf("Input Lastname \n");
    scanf(" %49s", students[0].lastname);

    printf("Input age ");
    scanf(" %d", &students[0].age);

    printf("Input Math Grade \n");
    scanf(" %d", &students[0].math_grade);

    printf("Input Physics Grade \n");
    scanf(" %d", &students[0].physics_grade);

    printf("Input Average Between the two \n");
    scanf(" %f", &students[0].average);

    // 打印学生信息
    printf("%s\n", students[0].firstname);
    printf("%s\n", students[0].lastname);
    printf("%d\n", students[0].age);
    printf("%d\n", students[0].math_grade);
    printf("%d\n", students[0].physics_grade);
    printf("%.2f\n", students[0].average);

    return 0;
}

这个方案不仅解决了你的乱码问题,还让代码的逻辑更清晰,后续扩展功能(比如存储多个学生)也更方便。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:38:02