您是否知道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;
}
答案 0 :(得分:0)
扫描错误:您需要从&
函数的scanf
中删除alegereStudent
才能读取stud.numeStudent
和stud.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()
可能是工作的错误工具。