为什么这段代码在尝试使用指针读取结构体实例时会抛出异常?

问题描述 投票:0回答:1

我们目前正在学习 C 语言的地址和指针逻辑,这是之前作为课堂作业给出的。每次运行此代码时,我都会在第一个 scanf_s 行之后抛出异常。

任何帮助将不胜感激!

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

struct Student
{
    char name[20];
    char id[10];
    float GPA;
};

void readStudent(struct Student* ptr) 
{
    printf("Enter name: ");
    scanf("%s\n", &ptr->name);

    printf("Enter id: ");
    scanf("%s\n", &ptr->id);

    printf("Enter GPA: ");
    scanf("%f\n", &ptr->GPA);
}
void printStudent(struct Student* ptr)
{
    printf("Name:%s\n", ptr->name);
    printf("ID:%s\n", ptr->id);
    printf("GPA:%f\n", ptr->GPA);
}

int main() 
{
    struct Student* ptr, student1;
    ptr = &student1;
    readStudent(ptr);
    printStudent(ptr);
}

更新:我将其更改为 scan_f 而不是 scanf_s,但现在它只接受第一个 scan_f 的输入,而不接受其他 scan_f 的输入。

c pointers
1个回答
0
投票

我测试了你的代码,实际上没有出现分段错误。但是当编译代码时,编译器通过列出的警告提供了一些线索。

    main.c|15|warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[20]’ [-Wformat=]|

这基本上是说,您正在引用一个正在输入字符串的“指向指针的指针”,在您的测试中,该字符串可能会尝试将您的输入存储到未定义的内存区域中。

此外,在“scanf”函数中,您不希望包含“ “(换行符),只是一个正确的格式引用(例如“%s”)。

这样,下面是一些重构的代码。

void readStudent(struct Student* ptr)
{
    printf("Enter name: ");
    scanf("%s", ptr->name);

    printf("Enter id: ");
    scanf("%s", ptr->id);

    printf("Enter GPA: ");
    scanf("%f", &ptr->GPA);             /* Here, the ampersand is proper */
}

此外,为了保持良好的礼仪,由于“main”函数预计返回整数值,因此最好在完成该函数时这样做。

int main()
{
    struct Student* ptr, student1;
    ptr = &student1;
    readStudent(ptr);
    printStudent(ptr);

    return 0;       /* Always a good idea to include when the function is expecting to output an integer value */
}

通过这些重构,以下是程序的测试运行。

craig@Vera:~/C_Programs/Console/StudentInfo/bin/Release$ ./StudentInfo 
Enter name: Craig
Enter id: 10-888-444
Enter GPA: 3.33
Name:Craig
ID:10-888-444
GPA:3.330000

因此,总而言之,要了解如何在“scanf”调用中引用指针,特别是对于作为字符数组的字符串。

© www.soinside.com 2019 - 2024. All rights reserved.