【C】学生成绩管理系统
这是用C写的学生成绩管理系统,需要StoneValley库的支持。本程序可以给读者做个参考。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include "StoneValley-master/src/svstring.h"
static const char * db_filename = "stu_database.dat";
typedef struct tag_StudentInfo
{
int id;
char name;
float chinese;
float math;
float english;
} StudentInfo, * PStudentInfo;
ARRAY_Z g_db = { 0 }; // Data base.
// Input students' credits.
void InputDegrees(PStudentInfo pinfo)
{
int i;
do
{
printf("Input student ID:%d. %s's credits by class.\n\t.Chinese.\n\t.Math\n\t.English\n\t.Return to upper menu.\n? ", pinfo->id, pinfo->name);
scanf_s("%d", &i);
switch (i)
{
case 1:
printf("Chinese:? ");
scanf_s("%f", &pinfo->chinese);
break;
case 2:
printf("Math:? ");
scanf_s("%f", &pinfo->math);
break;
case 3:
printf("English:? ");
scanf_s("%f", &pinfo->english);
break;
}
} while (i);
}
int LinearSearchDBByID(void * pitem, size_t param)
{
if (((PStudentInfo)pitem)->id == (int)0[((size_t *)param)])
return CBF_TERMINATE;
++1[((size_t *)param)];
return CBF_CONTINUE;
}
void InputStudentIDAndName(PStudentInfo pinfo)
{
size_t a;
StudentInfo infot = { 0 };
printf("Input student ID and name.\n");
Lbl_Input_ID:
printf("Student ID:? ");
scanf_s("%d", &infot.id);
a = infot.id;
a = 0;
if (CBF_TERMINATE == strTraverseArrayZ(&g_db, sizeof infot, LinearSearchDBByID, (size_t)a, FALSE))
{
printf("Student ID should be unique.\n");
goto Lbl_Input_ID;
}
printf("Student name:? ");
scanf_s("%s", infot.name, 15);
memcpy(pinfo, &infot, sizeof infot);
}
void PrintStudentInfo(PStudentInfo pinfo)
{
printf("%d\t%s\t%.2f\t%.2f\t%.2f\n", pinfo->id, pinfo->name, pinfo->chinese, pinfo->math, pinfo->english);
}
PStudentInfo FindStudentByID(int id)
{
size_t a;
a = id;
a = 0;
if (CBF_TERMINATE == strTraverseArrayZ(&g_db, sizeof(StudentInfo), LinearSearchDBByID, (size_t)a, FALSE))
return strLocateItemArrayZ(&g_db, sizeof(StudentInfo), a);
return NULL;
}
int LinearSearchDBByName(void * pitem, size_t param)
{
if (strcmp(((PStudentInfo)pitem)->name, (const char *)0[((size_t *)param)]) == 0)
{
PrintStudentInfo(pitem);
++1[((size_t *)param)];
}
return CBF_CONTINUE;
}
int LinearSearchDBByScore(void * pitem, size_t param)
{
float x, y, z;
x = *(float *)0[((size_t *)param)];
y = *(float *)1[((size_t *)param)];
switch (3[((size_t *)param)])
{
case 3: // Chinese.
z = ((PStudentInfo)pitem)->chinese;
if (z >= x && z <= y)
{
PrintStudentInfo(pitem);
++2[((size_t *)param)];
}
break;
case 4: // Math.
z = ((PStudentInfo)pitem)->math;
if (z >= x && z <= y)
{
PrintStudentInfo(pitem);
++2[((size_t *)param)];
}
break;
case 5: // English.
z = ((PStudentInfo)pitem)->english;
if (z >= x && z <= y)
{
PrintStudentInfo(pitem);
++2[((size_t *)param)];
}
break;
}
return CBF_CONTINUE;
}
void FindStudent(void)
{
size_t a;
int i, id;
char buffer = { 0 };
PStudentInfo pinfo;
float x, y;
do
{
printf("Find student.\n\t.By ID.\n\t.By name.\n\t.By Chinese score.\n\t.By Math score.\n\t.By English score.\n\t.Return to upper menu.\n? ");
scanf_s("%d", &i);
switch (i)
{
case 1:
printf("Input student ID:? ");
scanf_s("%d", &id);
pinfo = FindStudentByID(id);
if (pinfo)
{
printf("ID\tName\tChinese\tMath\tEnglish\n");
PrintStudentInfo(pinfo);
}
else
printf("Can not find student ID:%d.\n", id);
break;
case 2:
printf("Input student name:? ");
scanf_s("%s", buffer, 15);
a = (size_t)buffer;
a = 0;
printf("ID\tName\tChinese\tMath\tEnglish\n");
strTraverseArrayZ(&g_db, sizeof(StudentInfo), LinearSearchDBByName, (size_t)a, FALSE);
printf("%zd student(s) found.\n", a);
break;
case 3:
case 4:
case 5:
printf("Input lower bound for score: x? ");
scanf_s("%f", &x);
printf("Input upper bound for score: y? ");
scanf_s("%f", &y);
a = (size_t)&x;
a = (size_t)&y;
a = 0;
a = i;
printf("ID\tName\tChinese\tMath\tEnglish\n");
strTraverseArrayZ(&g_db, sizeof(StudentInfo), LinearSearchDBByScore, (size_t)a, FALSE);
printf("%zd student(s) found.\n", a);
break;
}
} while (i);
}
int ListStudentsInfo(void * pitem, size_t param)
{
PrintStudentInfo(pitem);
++0[((size_t *)param)];
return CBF_CONTINUE;
}
int cmp_student_id(const void * px, const void * py)
{
return ((PStudentInfo)px)->id - ((PStudentInfo)py)->id;
}
int cmp_student_name(const void * px, const void * py)
{
return strcmp(((PStudentInfo)px)->name, ((PStudentInfo)py)->name);
}
int cmp_student_chinese(const void * px, const void * py)
{
#define CLASS chinese
if (((PStudentInfo)px)->CLASS > ((PStudentInfo)py)->CLASS)
return 1;
else if (((PStudentInfo)px)->CLASS < ((PStudentInfo)py)->CLASS)
return -1;
return 0;
#undef CLASS
}
int cmp_student_math(const void * px, const void * py)
{
#define CLASS math
if (((PStudentInfo)px)->CLASS > ((PStudentInfo)py)->CLASS)
return 1;
else if (((PStudentInfo)px)->CLASS < ((PStudentInfo)py)->CLASS)
return -1;
return 0;
#undef CLASS
}
int cmp_student_english(const void * px, const void * py)
{
#define CLASS english
if (((PStudentInfo)px)->CLASS > ((PStudentInfo)py)->CLASS)
return 1;
else if (((PStudentInfo)px)->CLASS < ((PStudentInfo)py)->CLASS)
return -1;
return 0;
#undef CLASS
}
int cmp_student_total(const void * px, const void * py)
{
float x, y;
x = ((PStudentInfo)px)->chinese + ((PStudentInfo)px)->math + ((PStudentInfo)px)->english;
y = ((PStudentInfo)py)->chinese + ((PStudentInfo)py)->math + ((PStudentInfo)py)->english;
if (x > y)
return 1;
else if (x < y)
return -1;
return 0;
}
void SortStudentInfo(void)
{
int i;
size_t a = { 0 };
do
{
printf("Sort student information.\n\t.Sort student by ID.\n\t.Sort students by name.\n\t.Sort students Chinese score.\n\t.Sort students by Math score.\n\t.Sort students by English score.\n\t.Sort students by total score.\n\t.Return to upper menu.\n? ");
scanf_s("%d", &i);
switch (i)
{
case 1: // By ID.
strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_id);
break;
case 2: // By name.
strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_name);
break;
case 3: // By Chinese.
strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_chinese);
break;
case 4: // By Math.
strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_math);
break;
case 5: // By English.
strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_english);
break;
case 6: // By total score.
strSortArrayZ(&g_db, sizeof(StudentInfo), cmp_student_total);
break;
}
a = 0;
printf("ID\tName\tChinese\tMath\tEnglish\n");
strTraverseArrayZ(&g_db, sizeof(StudentInfo), ListStudentsInfo, (size_t)a, FALSE);
printf("%zd student(s) enlisted.\n", a);
} while (i);
}
int ComputeStatistics(void * pitem, size_t param)
{
PStudentInfo pinfo = (PStudentInfo)pitem;
float * chinese_total = (float *)0[(size_t *)param];
float * chinese_max = (float *)1[(size_t *)param];
float * chinese_min = (float *)2[(size_t *)param];
float * math_total = (float *)3[(size_t *)param];
float * math_max = (float *)4[(size_t *)param];
float * math_min = (float *)5[(size_t *)param];
float * english_total = (float *)6[(size_t *)param];
float * english_max = (float *)7[(size_t *)param];
float * english_min = (float *)8[(size_t *)param];
(*chinese_total) += pinfo->chinese;
(*math_total) += pinfo->math;
(*english_total) += pinfo->english;
if (*chinese_max < pinfo->chinese)
*chinese_max = pinfo->chinese;
if (*math_max < pinfo->math)
*math_max = pinfo->math;
if (*english_max < pinfo->english)
*english_max = pinfo->english;
if (*chinese_min > pinfo->chinese)
*chinese_min = pinfo->chinese;
if (*math_min > pinfo->math)
*math_min = pinfo->math;
if (*english_min > pinfo->english)
*english_min = pinfo->english;
++9[(size_t *)param];
return CBF_CONTINUE;
}
void Statistics(void)
{
int i;
float f = { 0.0 };
size_t a;
f = f = f = FLT_MAX;
f = f = f = FLT_MIN;
for (i = 0; i < 9; ++i)
a = (size_t)(f + i);
a = 0;
printf("Statistics for average, maximum and minimum score of three classes:\n");
strTraverseArrayZ(&g_db, sizeof(StudentInfo), ComputeStatistics, (size_t)a, FALSE);
printf("Chinese:\n\tAvg\tMax\tMin\n\t%0.2f\t%0.2f\t%0.2f\n", f / (float)a, f, f);
printf("Math:\n\tAvg\tMax\tMin\n\t%0.2f\t%0.2f\t%0.2f\n", f / (float)a, f, f);
printf("English:\n\tAvg\tMax\tMin\n\t%0.2f\t%0.2f\t%0.2f\n", f / (float)a, f, f);
}
void ReadDataBaseFile(void)
{
StudentInfo si;
FILE * fp;
fopen_s(&fp, db_filename, "rb");
if (fp)
{
while (!feof(fp))
{
fread(&si, sizeof si, 1, fp);
if (!feof(fp))
if (strResizeArrayZ(&g_db, strLevelArrayZ(&g_db) + 1, sizeof si))
strInsertItemArrayZ(&g_db, &si, sizeof si, strLevelArrayZ(&g_db) - 1);
}
fclose(fp);
}
}
int CBFWriteDataBase(void * pitem, size_t param)
{
fwrite(pitem, sizeof(StudentInfo), 1, (FILE *)param);
return CBF_CONTINUE;
}
void WriteDataBaseFile(void)
{
FILE * fp;
fopen_s(&fp, db_filename, "wb");
if (fp)
{
strTraverseArrayZ(&g_db, sizeof(StudentInfo), CBFWriteDataBase, (size_t)fp, FALSE);
fclose(fp);
}
}
int main(void)
{
int i, id;
size_t a;
StudentInfo si = { 0 }, * pinfo;
ReadDataBaseFile();
do
{
printf("Student Information Management System v%s.\n", LIB_VER);
printf(".Insert student.\n");
printf(".Remove student.\n");
printf(".List all students.\n");
printf(".Find student.\n");
printf(".Alter student's information.\n");
printf(".Sort student information.\n");
printf(".Statistics.\n");
printf(".Exit.\n? ");
scanf_s("%d", &i);
switch (i)
{
case 1:
InputStudentIDAndName(&si);
InputDegrees(&si);
if (strResizeArrayZ(&g_db, strLevelArrayZ(&g_db) + 1, sizeof si) && strInsertItemArrayZ(&g_db, &si, sizeof si, strLevelArrayZ(&g_db) - 1))
{
printf("Insertion succeeded!\n");
PrintStudentInfo(&si);
}
else
printf("Insertion failed!\n");
break;
case 2:
printf("Input student ID:? ");
scanf_s("%d", &id);
a = id;
a = 0;
if (CBF_TERMINATE == strTraverseArrayZ(&g_db, sizeof(StudentInfo), LinearSearchDBByID, (size_t)a, FALSE))
{
strRemoveItemArrayZ(&g_db, sizeof si, a, TRUE);
printf("Student information has been deleted!\n");
}
else
printf("Can not find student ID:%d.\n", id);
break;
case 3:
a = 0;
printf("ID\tName\tChinese\tMath\tEnglish\n");
strTraverseArrayZ(&g_db, sizeof(StudentInfo), ListStudentsInfo, (size_t)a, FALSE);
printf("%zd student(s) enlisted.\n", a);
break;
case 4:
FindStudent();
break;
case 5:
printf("Input student ID:? ");
scanf_s("%d", &id);
a = id;
a = 0;
if (CBF_TERMINATE == strTraverseArrayZ(&g_db, sizeof(StudentInfo), LinearSearchDBByID, (size_t)a, FALSE))
{
pinfo = (PStudentInfo)strLocateItemArrayZ(&g_db, sizeof si, a);
InputStudentIDAndName(pinfo);
InputDegrees(pinfo);
printf("Student information has been successfully altered!\n");
}
else
printf("Can not find student ID:%d.\n", id);
break;
case 6:
SortStudentInfo();
break;
case 7:
Statistics();
break;
}
} while (i);
WriteDataBaseFile();
PrintStudentInfo(&si);
strFreeArrayZ(&g_db);
return 0;
}
运行结果如下:
感觉只需要把strTraverseArrayZ这个函数自己实现一下就可以不用依赖StoneValley库了。
++0[((size_t *)param)]可还行。 0xAA55 发表于 2021-4-15 14:19
感觉只需要把strTraverseArrayZ这个函数自己实现一下就可以不用依赖StoneValley库了。
++0[((size_t *)par ...
哈哈哈太草了,这个只能忽悠C语言初学者吧!:lol 0xAA55 发表于 2021-4-15 14:19
感觉只需要把strTraverseArrayZ这个函数自己实现一下就可以不用依赖StoneValley库了。
++0[((size_t *)par ...
不行,还有strSortArrayZ和strResizeArrayZ等函数是库里的。这些函数支持定长数组组件的工作。
((size_t *)param)++;
*((size_t *)param)++;
也行。 watermelon 发表于 2021-4-18 18:53
哈哈哈太草了,这个只能忽悠C语言初学者吧!
有些时候++0[((size_t *)param)]这种写法比其他写法容易查看。
比如这种模式下:
float * chinese_total = (float *)0[(size_t *)param];
float * chinese_max = (float *)1[(size_t *)param];
float * chinese_min = (float *)2[(size_t *)param];
float * math_total = (float *)3[(size_t *)param];
float * math_max = (float *)4[(size_t *)param];
float * math_min = (float *)5[(size_t *)param];
float * english_total = (float *)6[(size_t *)param];
float * english_max = (float *)7[(size_t *)param];
float * english_min = (float *)8[(size_t *)param];
这种写法会容易查看并且很整齐。
页:
[1]