struct{
int year;
int unit;
int NumberOfSubject;
float gpa;
char semester[5];
char NameOfSubject[60][50];
char grade;
char name[40];
}student;
char CreatAccount(void)
{
int i;
char ans;
database= fopen("database.rtf", "w");
printf("tThis is registration pagen");
printf("Please enter your namen");
fgets(student.name,40,stdin);
printf("Is your name %s?, Y/Nn", student.name);
scanf("%c", &ans);
if (ans == 'y' || ans == 'Y')
{
printf("Registration is successfully completed!. Name on your account is %s",student.name);
fopen("database.txt", "w");
for (i=0; student.name[i] != 'n'; i++)
{
fputc(student.name[i], database);
}
fclose(database);
int i;
int j;
printf("Please enter yearn");
scanf("%d",&(student.year));
fflush(stdin);
printf("Please enter semestern");
fgets(student.semester,10,stdin);
printf("Please enter units you have takenn");
scanf("%d",&(student.unit));
printf("Please enter number of subjects you are taking at this momentn");
scanf("%d",&(student.NumberOfSubject));
fflush(stdin);
for (i=0; i<student.NumberOfSubject; i++)
{
printf("Please enter the name of subjects you are takingn");
fgets(student.NameOfSubject[i],50,stdin);
printf("Your %dth Subject is %sn",i+1,student.NameOfSubject[i]);
}
printf("Registration is completed! Here is your informationnn");
printf("Your year:%dn",student.year);
printf("Semester:%sn",student.semester);
printf("Units:%dn",student.unit);
for (j=0; j<student.NumberOfSubject; j++)
{
printf("Name of subjects:%s",student.NameOfSubject[j]);
}
printf("Number of subjects:%dn",student.NumberOfSubject);
}
我就是找不到这个问题的原因。当输出时,有些东西不应该出现在那里。我想找出这件事的原因。谢谢例如,如果我输入以下输入
2022年秋季学期
12个单位
3-受试者人数
数学、英语、物理
输出将是这样,
你的一年:2022
学期:秋天
english//不应该打印
//shouldn't be next-line space here
单位:12
科目名称:英文
科目名称:math
学科名称:物理
受试者人数:3人
fflush(stdin);
为未定义行为。
在fgets()
中length - 1
位置出现换行符。
同时,永远不要将scanf()
与fgets()
混合。
size_t len = strlen(str); // str is your string
if(str[len - 1] == 'n')
str[len - 1] = 0;
编辑:better one
str[strcspn(str, "n")] = ' '
您的代码中有几个问题:
- 您正在将
scanf
与fget
混合。它们的工作方式不同,所以你不应该同时使用它们(除非你非常小心)。 fflush(stdin)
是未定义的行为。冲洗stdin
的唯一方法是读取其中的内容。scanf
可能是一个危险的功能,如果你误用它(你显然是)。您需要检查它的返回值,如果失败,则执行一些操作。fgets
还读取换行符(按Enter时的字符)。你必须用空终止符替换它。
我就是找不到这个问题的原因。
以上最后一点解释了为什么。
scanf
不读取用户输入。它解析。这就是它的名字:scan format。扫描可能会失败,即使失败了,也不会损坏输入缓冲区。所以这取决于你是否">冲洗"(即清除或读取并丢弃其中的所有内容)
void fflush_stdin(void)
{
scanf("%*[^n]");
}
寻址scanf
失败是通过检查其返回值来完成的。从cppreference:
返回值
成功分配的接收参数数(如果在分配第一个接收参数之前发生匹配失败,则可能为零),或者如果在分配第一个接收参数之前发生输入失败,则为EOF。
bool read_char(const char *msg, char *c)
{
do {
printf("%s", msg);
int ret = scanf(" %c", c); // Note the extra space before %c. It means match all space characters before a given character is met.
switch (ret) {
case EOF: return false;
case 1: return true;
default:
flush_stdin();
printf("Input error.n");
break;
}
} while (true);
return true; // This won't run.
}
同样的事情也适用于int
s,float
s等。对于扫描字符串,您必须提供char
缓冲区的长度:
char buffer[100];
scanf("%99[^n]", buffer);