C:在main中调用struct函数时出错

时间:2018-10-14 15:46:50

标签: c function

您是否知道alegereStudent中的scanf为什么不起作用?控制台让我用空行写随机的东西,并在printf之后显示随机数。我正在尝试做一个初学者项目,但是我不知道为什么这个结构不能让我按照自己的意愿进行scanf。

代码:

#include<stdio.h>

struct student
{
    char numeStudent[20];
    char prenumeStudent[20];
    int idStudent;
    float medieAdmitere;
};

struct profesor
{
    char *numeProfesor[20];
    char *prenumeProfesor[20];
    char *domeniu[20];
};

void alegereStudent( struct student stud){
    printf("Introduceti Numele: %s", stud.numeStudent);
    scanf("%s\n",&stud.numeStudent);
    printf("Introduceti Prenumele:%s",stud.prenumeStudent);
    scanf("%s\n",&stud.prenumeStudent);
    printf("Introduceti ID-ul studentului:%d",stud.idStudent);
    scanf("%d\n",&stud.idStudent);
    printf("Introduceti Media de admitere:%f",stud.medieAdmitere);
    scanf("%f\n",&stud.medieAdmitere);
};

int main(void)
{
    int intrDate=0,cautDate=0,listDate=0,iesire=0,desprStudenti=0,desprProfesori=0,inapoi=0;
    struct student stud;
    printf("Meniu principal:\n\n");
    printf("1.Introducere date. %d\n",intrDate);
    printf("2.Cautare date.%d\n",cautDate);
    printf("3.Listare date.%d\n",listDate);
    printf("0.Iesire Aplicatie.%d\n",iesire);
    printf("Alegeti o optiune:");
    scanf("%d,%d,%d,%d",&intrDate,&cautDate,&listDate,&iesire);
    if(intrDate==1){
        printf("1. Despre studenti %d\n",desprStudenti);
        printf("2. Despre profesori\n");
        printf("3. Revenire la meniul principal\n");
        printf("Alegeti o optiune:");
        scanf("%d",&desprStudenti);
    }
    if(desprStudenti==1)
        alegereStudent(stud);

    return 0;
}

2 个答案:

答案 0 :(得分:0)

扫描错误:您需要从&函数的scanf中删除alegereStudent才能读取stud.numeStudentstud.prenumeStudent-您需要了解数组和指针。另外,您需要包括<stdio.h>并将;放在return 0之后。

错误原因:数组衰减为指针,scanf需要一个指针来将用户输入读入变量,因此无需放置&

建议:http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html

答案 1 :(得分:0)

alegereStudent()中的代码修改了局部变量stud,但这只是在main()中创建的未初始化结构的副本,它不会影响其中的结构。 main()

对于要在调用函数中修改结构的函数,必须将指针传递给该结构。然后,对结构成员的引用使用箭头->运算符而不是点.运算符。您不想打印出旧的(未初始化的)值;您要提示输入新值。而且,您不想在char (*)[20]函数期望一个简单的scanf()的情况下传递char *(指向20个字符的数组的指针),请从字符串中删除&

一个主要问题是you do NOT want a trailing newline in your scanf() format strings。这意味着用户必须键入非空格字符才能停止输入,而且人们也不擅长预测下一步需要做什么。您使用的所有转换都会跳过前导空格,包括换行符,因此您不必担心遗留换行符(或者,如果您要担心它,则不必使用{{ 1}},格式为\n

scanf()

这些格式将字符串限制为19个字符加一个空字节,因此您不会溢出,但它们不能确保您读取(并丢弃?)任何多余的字节。请记住:void alegereStudent(struct student *stud) { printf("Introduceti Numele: "); scanf("%19s", stud->numeStudent); printf("Introduceti Prenumele: "); scanf("%19s", stud.prenumeStudent); printf("Introduceti ID-ul studentului: "); scanf("%d", &stud.idStudent); printf("Introduceti Media de admitere: "); scanf("%f", &stud.medieAdmitere); } 会读取下一个空格字符。如果用户在第一行输入%s,则第一个Robin Hood将读取scanf(),下一个Robin(无需等待用户键入新数据。

还请注意,此功能后不需要分号。它标志着函数主体之后的空(变量?)声明的结束。

您当然需要在Hood函数中更改呼叫:

main()

最好不要将七个变量定义填充到一行中。实际上,通常最好每个变量使用一行。并使用更多空间。

if (desprStudenti == 1)
    alegereStudent(&stud);

int intrDate=0,cautDate=0,listDate=0,iesire=0,desprStudenti=0,desprProfesori=0,inapoi=0;

创建MCVE(Minimal, Complete, Verifiable Example)时,最好删除未使用的变量和类型定义,并消除菜单(只需调用需要执行的代码),等等。

另请参见A Beginner's Guide Away From scanf()int intrDate = 0; int cautDate = 0; int listDate = 0; int iesire = 0; int desprStudenti = 0; int desprProfesori = 0; int inapoi = 0; 函数是最难正确使用的函数之一。在简单的情况下,它使生活变得轻松,但是当事情开始变得棘手时,scanf()可能是工作的错误工具。