我创建了一个函数作为我的项目,名称搜索/姓氏搜索功能不起作用并给出运行时错误。我无法真正看到错误。那有什么不对呢?
ID和Mark搜索系统也有一些错误,每当你搜索一个ID时它也会带来mark = 0,如果你搜索Mark,它也会带来ID = 0.
完整代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Student
{
long long int id;
char firstname[20];
char lastname[20];
int mark;
} student;
void
storeRecord()
{
FILE *fp;
printf("\nEnter Student Details:\n\nID number: ");
scanf_s("%lld",&student.id);
printf("\nName:");
scanf_s("%19s",student.firstname);
printf("\nSurname:");
scanf_s("%19s",student.lastname);
printf("\nMark(0 - 100 integer) : ");
scanf_s("%d",&student.mark);
fp = fopen("studentfile.txt","a+"); /* check if the file was opened */
if (fp == NULL)
return;
fprintf(fp, "\n%lld\t%s\t%s\t%d\t",
student.id,
student.firstname,
student.lastname,
student.mark);
fclose(fp);
printf("A student record has been added successfully...\n");
getchar();
}
int
compareStudentsById(struct Student lhs, struct Student rhs)
{
return (lhs.id == rhs.id);
}
int
compareStudentsByName(struct Student lhs, struct Student rhs)
{
return (strcmp(lhs.firstname, rhs.firstname) == 0);
}
int
compareStudentsByLastame(struct Student lhs, struct Student rhs)
{
return (strcmp(lhs.lastname, rhs.lastname) == 0);
}
int
compareStudentsByMark(struct Student lhs, struct Student rhs)
{
return (lhs.mark == rhs.mark);
}
void
printStudent()
{
printf("\nThe record is found.\n");
printf("\nID: %lld\nName: %s\nSurname: %s\nMark: %d \n",
student.id,
student.firstname,
student.lastname,
student.mark
);
}
void
searchStudent(int(*compare)(struct Student,struct Student), const char *const name, const char *const lastname, long long int id, int mark)
{
FILE *fp;
int found;
int matches;
if (name != NULL)
printf("Searching record with Name = %s.\n", name);
if (lastname != NULL)
printf("Searching record with Surname = %s.\n", lastname);
if (id != -1)
printf("Searching record with ID = %lld.\n", id);
if (mark != -1)
printf("Searching record with Mark = %d.\n", mark);
found = 0;
fp = fopen("studentfile.txt", "r");
if (fp == NULL)
{
printf("IO error\n");
return;
}
do
{
struct Student other;
if (name != NULL)
strcpy(other.firstname, name);
if (lastname != NULL)
strcpy(other.lastname, lastname);
other.id = id;
other.mark = mark;
matches = fscanf(fp,"\n%lld\t%s\t%s\t%d\t",
&student.id,
student.firstname,
student.lastname,
&student.mark);
if (matches == 4)
found = (compare(student, other) != 0);
} while ((matches == 4) && (found == 0));
if (found != 0)
printStudent();
else
printf("Not found...\n");
getchar();
}
void
searchStudentByName()
{
char studentname[20];
printf("\nEnter student first name: ");
scanf_s("%19s", studentname);
searchStudent(compareStudentsByName, studentname, NULL, NULL, NULL);
}
void
searchStudentById()
{
long long int id;
printf("\nEnter ID: ");
scanf_s("%lld", &id);
searchStudent(compareStudentsById, NULL, NULL, id, NULL);
}
void
searchStudentByLastname()
{
char studentlastname[20];
printf("\nEnter student surname: ");
scanf_s("%19s", &studentlastname);
searchStudent(compareStudentsByLastame, NULL, studentlastname, NULL, -1);
}
searchStudentByMark()
{
int mark;
printf("\nEnter Mark: ");
scanf_s("%d", &mark);
searchStudent(compareStudentsByMark, NULL, NULL, NULL, mark);
}
int main()
{
int choice;
choice = 0;
while (choice != 5)
{
printf("\n\tC PROGRAM OF STUDENT DATABASE SYSTEM");
printf("\n1 -> Store a new record in database\n");
printf("2 -> Search a student record by Student First Name\n");
printf("3 -> Search a student record by ID\n");
printf("4 -> Search a student record by Surname\n");
printf("5 -> Search a student record by Mark\n");
printf("6 -> Quit Student Database");
printf("\n\n");
printf("Enter your choice : ");
scanf_s("%d",&choice);
switch(choice)
{
case 1:
storeRecord();
break;
case 2:
searchStudentByName();
break;
case 3:
searchStudentById();
break;
case 4:
searchStudentByLastname();
break;
case 5:
searchStudentByMark();
break;
}
}
getch();
return 0;
}
答案 0 :(得分:0)
如果您已经编译了此代码,并且警告已打开(正如每个人都应该这样做)并修复了警告,那么这个(修改过的)程序将大部分工作。通过Mark搜索工作但结束程序。我会把它留给你解决的问题。
void
printStudent()
{
printf("\nThe record is found.\n");
printf("\nID: %lld\nName: %s\nSurname: %s\nMark: %d \n",
student.id,
student.firstname,
student.lastname,
student.mark
);
}
void
searchStudent(int(*compare)(struct Student,struct Student), const char *const name, const char *const lastname, long long int id, int mark)
{
FILE *fp;
int found;
int matches;
if (name != 0)
printf("Searching record with Name = %s.\n", name);
if (lastname != 0)
printf("Searching record with Surname = %s.\n", lastname);
if (id != -1)
printf("Searching record with ID = %lld.\n", id);
if (mark != -1)
printf("Searching record with Mark = %d.\n", mark);
found = 0;
fp = fopen("studentfile.txt", "r");
if (fp == 0)
{
printf("IO error\n");
return;
}
do
{
struct Student other;
if (name != NULL)
strcpy(other.firstname, name);
if (lastname != NULL)
strcpy(other.lastname, lastname);
other.id = id;
other.mark = mark;
matches = fscanf(fp,"\n%lld\t%s\t%s\t%d\t",
&student.id,
student.firstname,
student.lastname,
&student.mark);
if (matches == 4)
found = (compare(student, other) != 0);
} while ((matches == 4) && (found == 0));
if (found != 0)
printStudent();
else
printf("Not found...\n");
getchar();
}
void
searchStudentByName()
{
char studentname[20];
printf("\nEnter student first name: ");
scanf("%19s", studentname);
searchStudent(compareStudentsByName, studentname, 0, 0, 0);
}
void
searchStudentById()
{
long long int id;
printf("\nEnter ID: ");
scanf("%lld", &id);
searchStudent(compareStudentsById, 0, 0, id, 0);
}
void
searchStudentByLastname()
{
char studentlastname[20];
printf("\nEnter student surname: ");
scanf("%19s", studentlastname);
searchStudent(compareStudentsByLastame, 0, studentlastname, 0, -1);
}
searchStudentByMark()
{
int mark;
printf("\nEnter Mark: ");
scanf("%d", &mark);
searchStudent(compareStudentsByMark, 0, 0, 0, mark);
}
int main()
{
int choice;
choice = 0;
while (choice != 5)
{
printf("\n\tC PROGRAM OF STUDENT DATABASE SYSTEM");
printf("\n1 -> Store a new record in database\n");
printf("2 -> Search a student record by Student First Name\n");
printf("3 -> Search a student record by ID\n");
printf("4 -> Search a student record by Surname\n");
printf("5 -> Search a student record by Mark\n");
printf("6 -> Quit Student Database");
printf("\n\n");
printf("Enter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
storeRecord();
break;
case 2:
searchStudentByName();
break;
case 3:
searchStudentById();
break;
case 4:
searchStudentByLastname();
break;
case 5:
searchStudentByMark();
break;
case 6:
goto lend;
}
}
lend:;
return 0;
}
提示:向default
添加包含错误消息的switch(choice)
子句,并将if (choice != 5)
更改为更好的测试。
答案 1 :(得分:0)
扫描像scanf_s("%19s", ...);
这样的字符串的多次使用都不正确。
请勿使用&amp;在studentlastname
之前。
同时传递缓冲区的大小。这是scanf()
和scanf_s()
之间的主要区别:为char *
参数传递的大小。如果没有适当的参数,可能会发生seg故障或其他奇怪的行为。
检查scanf_s()
char studentname[20];
// scanf_s("%19s", &studentlastname);
if (1 != scanf_s("%s", studentlastname, sizeof studentlastname)) {
Handle_Error();
}
IMO:不要对任何用户输入使用scanf()
或scanf_s()
。而是使用fgets()
和sscanf()
或sscanf_s()
等
char studentname[20];
char buffer[2 * sizeof studentname + 2]; // I like 2x buffers
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
Handle_EOF();
}
if (1 != sscanf("%19s", studentlastname)) {
Handle_Error();
}
// or
if (1 != sscanf_s("%s", studentlastname, sizeof studentlastname)) {
Handle_Error();
}
如果以这种方式更改所有用户输入,包括获取数字的用户输入,则从scanf()
更改为fgets()
确实效果最佳。
int main()
- &gt; int main(void)
@Dirk Koopman
如果您的环境需要最终的getch()
,请考虑删除它。
BTW良好的退出策略,检查matches = fscanf(fp,...
的结果,好的代码没有使用feof()
。