我该如何解决这个错误?开关语句

How do i fix this error? Switch statement

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

struct student
{
    char name[30];
    char dob[30];
    int rollno;
    float percent;
    int sub[3];
    int total;
};

int main(void)
{
    int i, n,a,c,*ptr;
    char ch;
    struct student *st;
    
    printf("Enter number of students data you want to enter:\n");
    scanf("%d",&n);

    st=(struct student*) malloc(n * sizeof(struct student));

    if(st == NULL) 
    {
        printf("Error! memory not allocated.");
        exit(0);
    }

    for(i=1;i <= n;i++)
    {
        printf("Enter name of student %d\n",(i));
        scanf("%s",&(st+i)->name);
        printf("Enter Roll No of student %d\n",(i));
        scanf("%d",&(st+i)->rollno);
        printf("Enter Date Of Birth of student %d\n",(i));
        scanf("%s",&(st+i)->dob);
        printf("Enter marks for 3 subjects of student %d\n",(i));
        scanf("%d %d %d",&(st+i)->sub[0],&(st+i)->sub[1],&(st+i)->sub[2]);
        (st+i)->total = ((st+i)->sub[0]+(st+i)->sub[1]+(st+i)->sub[2]);
        printf("Total Marks of student %d = %d\n\n",(i), (st+i)->total);
    }
    printf("\n");

    printf("\n<1>To display details of students\n");
    printf("\n<2>exit\n");
    printf("Enter your choice:\n");
    scanf("%c",&ch);

    switch(ch)
    {
    case '1':
    {      
        for(i=1; i <= n;i++)
        { 
            printf("\n%d.%s",(st+i)->rollno,(st+i)->name);
        }

        printf("\n Enter Roll no to display info of student");
        scanf("%d",&a);

        {
            c=a;
            a=i;
            i=c;

        if((st+i)->sub[0]<33||(st+i)->sub[1]<33||(st+i)->sub[2]<33)
        {   
            printf("\nName of student: %s",(st+i)->name);
            printf("\nRoll No of student: %d",(st+i)->rollno);
            printf("\nDate of Birth : %s",(st+i)->dob);
            printf("\nTotal of student: %d",(st+i)->total);
            printf("\nStudent Status fail");
            return 0;
        }

        printf("\nName of student: %s",(st+i)->name);
        printf("\nRoll No of student: %d",(st+i)->rollno);
        printf("\nDate of Birth : %s",(st+i)->dob);
        printf("\nTotal of student: %d",(st+i)->total);

        (st+i)->percent=((st+i)->total)/3;

        printf("\nPercent of Student = %f",(st+i)->percent);

        if((st+i)->percent>=33)
        {
            printf("\nStudent status:- PASS\n");
        }
        else
            printf("\nStudent status:-FAIL\n");

        if((st+i)->percent>=90)
            printf("Grade= A1\n");
        else if (80<=(st+i)->percent)
            printf("Grade= A2\n");
        else if(70<=(st+i)->percent)
            printf("Grade= B1\n");
        else if(60<=(st+i)->percent)
            printf("Grade= B2\n");
        else if(50<=(st+i)->percent)
            printf("Grade= C1\n");
        else if(40<=(st+i)->percent)
            printf("Grade= C2\n");
        else if(33<=(st+i)->percent)
            printf("Grade= D\n");
        else if((st+i)->percent<33)
            printf("Grade= F\n");
        }

        break;
    }

    case '2':
    {
        return 0;
    }

    default:
        printf("Invalid! Try again...\n");
    }

    free(st);
    return 0;
}

我想让我的程序输入学生的各种详细信息,并在我输入卷号时显示它们。学生。然而, switch 语句没有执行;该程序在接受输入后就退出了。 我检查了语法,但它是正确的我不知道问题是什么。 如果我能得到有关该问题的提示,那就太好了。

使用 getchar() 而不是 scanf()。这是因为 scanf 会在输入流中留下您键入的换行符。尝试

do
   ch = getchar();
while (isspace(ch));

问题与 switch 语句无关,但与写入和读取正确的内存位置有关。

在 C 中,数组从索引 0 开始。因此,第一个 for 循环尝试访问分配的内存之外的内存。惯用的解决方案是从 i 开始并在它严格小于数组大小时循环。

此处不需要指针算法来访问数组成员,最好用索引运算符 ([]) 代替。更重要的是,请仔细查看 scanf 期望的类型和参数的实际类型。 namedob 变量已经是 char* 类型(或 char[30] 指针衰减),因此它们不需要额外的“地址”运算符(&).查看编译器警告有助于捕获此类错误。

这是包含改进建议的代码:

for(i=0;i < n;i++)
{
    printf("Enter name of student %d\n",(i));
    scanf("%s",st[i].name);
    printf("Enter Roll No of student %d\n",(i));
    scanf("%d",&st[i].rollno);
    printf("Enter Date Of Birth of student %d\n",(i));
    scanf("%s",st[i].dob);
    // ...

解决此问题后,代码现在会跳过 switch 菜单,因为输入中已经有一个由 scanf 读取的换行符 (\n)。要跳过前导白色 space(包括换行符),请在字符转换说明符前添加一个 space 字符 ( ):

scanf(" %c",&ch);

在 switch 语句中,将与之前相同的修复应用于 for 循环:

for(i=0; i < n;i++)

下面是更多的无效读取,可能是c=a; a=i; i=c;造成的,我不确定这背后的想法是什么。
我希望上面的建议可以帮助您自己解决其他问题,而不是修复整个程序。首先编写简短的独立代码片段并对其进行全面测试(例如,通过写入特定内存然后从中读取)然后将这些片段合并到更大的程序中可能会有所帮助。 此外,使用调试信息(-g 标志)和 运行 使用 Valgrind 编译程序可以帮助您追踪错误的来源。

最后,小心使用scanf来读取字符串。目前,如果输入字符串长于写入数组的大小,可能会导致缓冲区溢出。例如,使用 scanf("%29s",st[i].name); 来限制 scanf 将读取的最大字符数。安全和可预测地阅读输入比我在这里写的要多,所以我鼓励你自己看看 Stack Overflow 或其他地方。