C语言-结构体-学生成绩录入-scanf_s()字符串输入缓存区参数问题

发布者: 站长-R 分类: C++/C,IT技术交流 发布时间: 2025-12-10 22:50 访问量: 100 次浏览

在学习结构体时候,在给其赋值时突然报错,详细看是scanf_s()报错了,我们来看一下是什么原因,下面是原始报错代码

#include <stdio.h>
typedef struct Studt{
    char id[20];
    char name[20];
    int sorce1;
    int sorce2;
    int sorce3;
}Student;

void stuSorce() {
    int n = 0;
    scanf_s("%d", &n);
    Student stu[100],first;
    int maxTotal = 0;
    int nowTotal = 0;
    for (int i = 0; i < n; i++) {
        scanf_s("%s %s %d %d %d", &stu[i].id,
                                    &stu[i].name,
                                    &stu[i].sorce1,
                                    &stu[i].sorce2,
                                    &stu[i].sorce3);
    }
    first = stu[0];
    maxTotal = stu[0].socre1 + stu[0].socre2 + stu[0].socre3;
    for (int i = 0; i < n;i++) {
        nowTotal = stu[i].sorce1 + stu[i].sorce2 + stu[i].sorce3;
        if (nowTotal > maxTotal) {
            maxTotal = nowTotal;
            first = stu[i];
        }
    }
    printf("%s %s %d %d %d", first.id, first.name, first.sorce1, first.sorce2, first.sorce3);

}

报错

`1>正在生成代码...
1>D:\program-pack\c\cStudyPro\cStudyPro\stuSorce.c(18,11): warning C4477: “scanf_s”: 格式字符串“%s”需要类型“unsigned int”的参数,但可变参数 2 拥有了类型“char (*)[20]”
1>    D:\program-pack\c\cStudyPro\cStudyPro\stuSorce.c(18,11):
1>    此参数用作缓冲区大小
1>D:\program-pack\c\cStudyPro\cStudyPro\stuSorce.c(18,11): warning C4477: “scanf_s”: 格式字符串“%s”需要类型“char *”的参数,但可变参数 3 拥有了类型“int *”
1>    D:\program-pack\c\cStudyPro\cStudyPro\stuSorce.c(18,11):
1>    此参数由转换说明符使用
1>D:\program-pack\c\cStudyPro\cStudyPro\stuSorce.c(18,11): warning C4477: “scanf_s”: 格式字符串“%s”需要类型“unsigned int”的参数,但可变参数 4 拥有了类型“int *”
1>    D:\program-pack\c\cStudyPro\cStudyPro\stuSorce.c(18,11):
1>    此参数用作缓冲区大小
1>D:\program-pack\c\cStudyPro\cStudyPro\stuSorce.c(18,11): warning C4473: “scanf_s”: 没有为格式字符串传递足够的参数
1>    D:\program-pack\c\cStudyPro\cStudyPro\stuSorce.c(18,11):
1>    占位符和其参数预计 7 可变参数,但提供的却是 5 参数
1>    D:\program-pack\c\cStudyPro\cStudyPro\stuSorce.c(18,11):
1>    缺失的可变参数 6 为格式字符串“%d”所需
1>cStudyPro.vcxproj -> D:\program-pack\c\cStudyPro\x64\Debug\cStudyPro.exe
1>已完成生成项目“cStudyPro.vcxproj”的操作。`

scanf_s()问题所在

很明显,有问题的仅仅是scanf_s()这一句有问题,很明显,在struct中,id和name是char类型的数组,而socre申请的是一个int类型的变量,这里属于疏忽了,数组本身便是第一个元素的地址,因此不需要取地址符&,(尽管这里申请了student类型的stu数组,我们不考虑这一个,我们仅仅考虑student结构中的成员的类型,类似于类与对象中的)

然后最重要的是,在virtual studio中,scanf_s()用来输入字符串类型的数据时,为了防止缓存溢出,需要缓存区大小的参数。
scanf_s("%s", buffer, buffer_size);

  • 第一个参数:格式字符串 "%s"
  • 第二个参数:字符数组的起始地址(数组名)
  • 第三个参数:缓冲区大小(数组元素个数)
    这里的缓存区大小,即我们申请的char数组的长度,即(unsigned)sizeof(stu[i].id),我们需要把sizeof返回的size_t的数据类型转换为unsigned int类型。

    最终修改后

    #include <stdio.h>
    typedef struct Studt{
    char id[20];
    char name[20];
    int socre1;
    int socre2;
    int socre3;
    }Student;
    void stuSorce() {
    int n = 0;
    scanf_s("%d", &n);
    Student stu[100],first;
    int maxTotal = 0;
    int nowTotal = 0;
    for (int i = 0; i < n; i++) {
        scanf_s("%s %s %d %d %d", stu[i].id, (unsigned)sizeof(stu[i].id),
                                    stu[i].name, (unsigned)sizeof(stu[i].name),
                                    &stu[i].socre1,
                                    &stu[i].socre2,
                                    &stu[i].socre3);
    }
    first = stu[0];
    maxTotal = stu[0].socre1 + stu[0].socre2 + stu[0].socre3;
    for (int i = 0; i < n;i++) {
        nowTotal = stu[i].socre1 + stu[i].socre2 + stu[i].socre3;
        if (nowTotal > maxTotal) {
            maxTotal = nowTotal;
            first = stu[i];
        }
    }
    printf("%s %s %d %d %d", first.id, first.name, first.socre1, first.socre2, first.socre3);
    }

    如果觉得本站对您有帮助,请随意赞赏。您的支持将鼓励本站走向更好!!

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注