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

C语言字符串与数组使用崩溃排查:scanf_s格式符问题求助

栈Cookie校验失败与输入异常修复方案

编程作业中使用字符串时程序崩溃,触发gs_report.c中的以下代码:

if (IsProcessorFeaturePresent(PF_FASTFAIL_AVAILABLE))
{
    __fastfail(FAST_FAIL_STACK_COOKIE_CHECK_FAILURE);
}

同时存在输入异常:用%s格式符读取姓名时崩溃,用%c时循环自动执行无需用户输入。作业要求用字符串数组存储5个学生姓名、字符数组存储字母成绩、二维double数组存储4门测试分数,实现输入、平均分计算与等级展示。

代码错误分析

  • 姓名输入逻辑错误:
    原代码用scanf_s("%c", &names[i]);,names[i]是对应单个学生姓名的char数组,%c仅读取单个字符,且之前输入操作残留的换行符会被%c直接读取,导致后续循环跳过用户输入。使用%s时未传入缓冲区大小参数,导致scanf_s写入越界,破坏栈结构引发崩溃。
  • 分数求和越界访问:
    原代码中sum += scores[i][j];位于内层循环之后,此时j的值为4(循环条件j<4结束后自增到4),但scores[i]的下标范围是0-3,越界访问栈内存破坏了栈Cookie,触发崩溃。
  • 冗余代码:
    初始对grades数组的赋值会被后续等级判断覆盖,无实际作用可删除。

修复后的完整代码

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

int main()
{
    char names[5][100], grades[5]; // 修正为5个学生的姓名数组,每个姓名最多99字符+终止符
    int i, j;
    double scores[5][4], averages[5];

    for (i = 0; i < 5; i++)
    {
        double sum = 0;
        printf("enter the name of student %d: ", i + 1);
        // 使用scanf_s读取字符串,传入缓冲区大小避免越界
        scanf_s("%s", names[i], (unsigned)_countof(names[i]));
        // 清除输入缓冲区残留的换行符
        while (getchar() != '\n');

        for(j = 0; j < 4; j++)
        {
            printf("enter test score number %d: ", j + 1);
            scanf_s("%lf", &scores[i][j]);
        }
        // 清除分数输入后的换行符
        while (getchar() != '\n');

        // 在内层循环中累加分数,避免下标越界
        for(j = 0; j < 4; j++)
        {
            sum += scores[i][j];
        }
        averages[i] = sum / 4;

        if (averages[i] >= 90) 
        {
            grades[i] = 'A';
        }
        else if (averages[i] >= 80)
        {
            grades[i] = 'B';
        }
        else if (averages[i] >= 70)
        {
            grades[i] = 'C';
        }
        else if (averages[i] >= 60)
        {
            grades[i] = 'D';
        }
        else
        {
            grades[i] = 'F';
        }
    }

    printf("\n%-20s%-20s%-20s\n", "Student Name", "Average Test Score", "Letter Grade");
    printf("------------------------------------------------------------\n");

    for (i = 0; i < 5; i++)
    {
        printf("%-20s%-20.2lf%-20c\n", names[i], averages[i], grades[i]);
    }

    return 0;
}

关键修改说明

  1. 修正数组维度:将names[100][100]改为names[5][100],匹配作业要求的5个学生,减少不必要的内存占用。
  2. 安全读取字符串:使用scanf_s("%s", names[i], (unsigned)_countof(names[i])),_countof自动获取缓冲区大小,避免写入越界;每次输入后清除缓冲区的换行符,防止干扰下一次输入。
  3. 修复求和逻辑:将分数累加操作放到内层循环中,遍历合法下标0-3,正确计算总分。
  4. 优化用户提示:调整提示文本的格式,让输入引导更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 09:33:32