最后,将写完的代码贴上来
一点说明: 1、目前还有一些bug,在ID被判重复后输入0,有时会使得程序崩溃,时间原因尚未解决 2、中英文的注释混杂,并不是一个好习惯。写的过程中试图让自己以全英文注释,并严格按格式注释。但由于时间关系或英文水平的限制,既没有按照格式来注释,也没有做到全英文。 3、链表的建立、validate并不是很让我满意,感觉还有可以优化的地方。 4、sort用了选择排序,find只是逐个比较来查找,并没有学到什么新的算法,也没有搜一搜适合链表的查找算法。这里或许可以做很多优化。 5、文件的读写过于频繁。还不会随机读写,或许这里也可以进一步优化。 6、之所以主界面里面没有单独的排序功能,是因为添加、更新数据后都会重新排序一次并保存在文件中。 7、交互界面并不令我满意。很简陋。 8、在前期没有把函数的实现方法想明白,导致main.c中controller函数很复杂。或许可以改进一下delete、update等函数,使得代码更简洁,重复代码更少。并且使得variance、delete、update等函数用法更加一致。 9、程序写完之后才意识到没有输出均值,于是临时添加全局变量m_ave。 10、在学生姓名发生重复时,无法同时查找到这些学生。
——————————————
20170508修复了update时无法更新的问题。
——————————————
20170520结构体可以用=直接赋值,可以将swap函数省略了但还没有改
——————————————
app.c
#include "final.h"
stu *sort(stu *head)
{
stu *p1, *p2, *min;
for (p1 = head->next; p1->next != NULL; p1 = p1->next)
{
min = p1;
for (p2 = p1->next; p2; p2 = p2->next)
{
if (p2->cls<min->cls)
min = p2;
else
{
if (p2->cls == min->cls)
{
if (
strcmp(p2->name, p1->name) <
0)
{
swapStu(p1, p2);
}
}
}
}
if (min != p1)
swapStu(p1, min);
}
saveStu(head->next,
0);
m_head = head;
return head;
}
int validate(stu *head,
int id)
{
stu *p = head;
int flag =
0;
while (p->next)
{
if (p->next->id == id)
{
if (flag)
return 1;
flag++;
}
p = p->next;
}
if (m_head != head)
{
p = m_head;
if (p == NULL)
return 0;
while (p->next)
{
if (p->next->id == id)
return 1;
else
p = p->next;
}
return 0;
}
}
float varianceStu(stu *head)
{
int flag = -
1;
int n =
0;
int idmax=
0, idmin=
0;
int id =
0;
float var=
0, sum=
0, ave=
0;
int i =
0;
stu *p = head;
printf(
"\ninput 0 to get all students' variance");
printf(
"\ninput 1 to get variance of students of a class");
printf(
"\ninput 2 to get varicance of students of a range of ids\n");
scanf(
"%d", &flag);
switch (flag)
{
case 0:
for (i =
0; i < m_n; i++)
{
sum += p->next->sum;
p = p->next;
}
ave = sum / m_n;
p = head;
for (i =
0; i < m_n; i++)
{
var += (p->next->sum - ave)*(p->next->sum - ave);
p = p->next;
}
var /= m_n;
break;
case 1:
printf(
"\nPlease input class:");
int cls =
0;
scanf(
"%d", &cls);
for (i =
0; i < m_n; i++)
{
if (p->next->cls == cls)
{
sum += p->next->sum;
n++;
}
p = p->next;
}
ave = sum / n;
p = head;
for (i =
0; i < m_n; i++)
{
if (p->next->cls == cls)
{
var += (p->next->sum - ave)*(p->next->sum - ave);
}
p = p->next;
}
var /= n;
break;
case 2:
printf(
"\nPlease input the range of ID:(from...to...)");
scanf(
"%d%d", &idmin, &idmax);
if (idmin > idmax)
return 0;
p = head; n =
0;
for (i =
0; i < m_n; i++)
{
if (p->next->id >= idmin && p->next->id <= idmax)
{
sum += p->next->sum;
n++;
}
p = p->next;
}
ave = sum / n;
p = head;
for (i =
0; i < m_n; i++)
{
if (p->next->id >= idmin && p->next->id <= idmax)
{
var += (p->next->sum - ave)*(p->next->sum - ave);
}
p = p->next;
}
var /= n;
break;
default:
break;
}
m_ave=ave;
return var;
}
stu *create()
{
int i =
0;
stu *head = NULL;
stu *p1 = NULL, *p2 = NULL;
p1 = (stu *)
malloc(LEN);
if (p1 == NULL)
{
printf(
"\nFail to create it,please try again later.\n");
return NULL;
}
head = p1;
head->id = -
1;
p2 = p1 = (stu *)
malloc(LEN);
if (p1 == NULL)
{
printf(
"\nFail to create it,please try again later.\n");
return NULL;
}
else
{
head->next = p1;
p1->next = NULL;
printf(
"\nPlease input student ID(0 to stop):");
scanf(
"%d", &(p1->id));
}
if (p1->id ==
0)
{
return 0;
}
while (p1->id !=
0)
{
p2->next = p1;
p1->next = NULL;
if (validate(head, p1->id))
{
printf(
"\nThis id has already existed,please try again.");
printf(
"\nPlease input student ID(0 to stop):");
scanf(
"%d", &(p1->id));
if (p1->id ==
0) p2->next = NULL;
continue;
}
else
{
p2->next = p1;
p2 = p1;
printf(
"\nPlease input class:");
scanf(
"%d", &(p1->cls));
printf(
"\nPlease input name(no more than 20 characters):");
fflush(stdin);
gets(p1->name);
printf(
"\nPlease input scores of 3 subjects:");
p1->sum =
0;
for (i =
0; i <
3; i++)
{
scanf(
"%f", &(p1->score[i]));
p1->sum += p1->score[i];
}
m_n++;
p2->next = NULL;
p1 = (stu *)
malloc(LEN);
if (p1 == NULL)
{
printf(
"\nFail to create it,please try again later.\n");
return NULL;
}
else
{
printf(
"\nPlease input student ID(0 to stop):");
scanf(
"%d", &(p1->id));
}
}
}
free(p1);
saveStu(head->next,
1);
return sort(readStu());
}
void showStu(stu *p)
{
if (p == NULL)
{
printf(
"No such a student");
return;
}
printf(
"\n%-20s|]|]|%6.1f|%6.1f|%6.1f|%5.1f", p->name, p->id, p->cls, p->score[
0], p->score[
1], p->score[
2], p->sum);
}
void deleteStu(stu *p)
{
if (p == NULL)
{
printf(
"\nNo such a student.");
return;
}
stu *temp = p->next;
p->next = p->next->next;
free(temp);
saveStu(m_head->next,
0);
m_n--;
}
void updateStu(stu *p)
{
if (p == NULL)
{
printf(
"\nNo such a student");
return;
}
showTitle();
showStu(p);
int i, temp, temp2;
printf(
"\nPlease input student ID:");
scanf(
"%d", &temp);
if (temp ==
0)
return;
if (temp !=
0 && temp != p->id)
{
while (validate(m_head, temp))
{
printf(
"\nThis id has already existed,please try again.");
printf(
"\nPlease input student ID(0 to stop):");
scanf(
"%d", &temp);
if (temp ==
0)
return;
if (temp == p->id)
break;
}
}
p->id = temp;
printf(
"\nPlease input class:");
scanf(
"%d", &(p->cls));
printf(
"\nPlease input name(no more than 20 characters):");
fflush(stdin);
gets(p->name);
printf(
"\nPlease input scores of 3 subjects:");
p->sum =
0;
for (i =
0; i <
3; i++)
{
scanf(
"%f", &(p->score[i]));
p->sum += p->score[i];
}
saveStu(m_head->next,
0);
sort(m_head);
}
——————————————
common.c
#include "final.h"
stu *findStu(stu *head,
int id,
char *name)
{
if (id ==
0)
{
while (head->next)
{
if (
strcmp(head->next->name, name) ==
0)
return head;
else
head = head->next;
}
return NULL;
}
else
{
while (head ->next)
{
if (head->next->id == id)
return head;
else
head = head->next;
}
return NULL;
}
return 0;
}
void swapStu(stu *p1, stu *p2)
{
int tempi;
float tempf;
char tempc[
20];
int i =
0;
tempi = p1->id;
p1->id = p2->id;
p2->id = tempi;
tempi = p1->cls;
p1->cls = p2->cls;
p2->cls = tempi;
strcpy(tempc, p1->name);
strcpy(p1->name, p2->name);
strcpy(p2->name, tempc);
for (i =
0; i <
3; i++)
{
tempf = p1->score[i];
p1->score[i] = p2->score[i];
p2->score[i] = tempf;
}
tempf = p1->sum;
p1->sum = p2->sum;
p2->sum = tempf;
}
——————————————
file.c
#include "final.h"
void saveStu(stu *head,
int flag)
{
if (!head)
{
return;
}
FILE *fp = NULL;
if (flag ==
1)
fp = fopen(_FILENAME_,
"ab");
else
{
if (flag ==
0)
fp = fopen(_FILENAME_,
"wb");
}
if (fp == NULL)
{
fp = fopen(_FILENAME_,
"wb");
if (fp == NULL)
{
printf(
"\nCannot open or create the file");
return;
}
}
do
{
fwrite(head,
sizeof(stu),
1, fp);
head = head->next;
}
while (head);
fclose(fp);
}
stu *readStu()
{
stu *head = NULL, *tail = NULL, *p1 = NULL;
FILE *fp;
fp = fopen(_FILENAME_,
"rb");
if (fp == NULL)
{
fp = fopen(_FILENAME_,
"wb");
if (fp == NULL)
printf(
"Fail to open or create %s in function readStu", _FILENAME_);
return NULL;
}
m_n =
0;
p1 = (stu *)
malloc(LEN);
if (p1 == NULL)
{
printf(
"Fail to allocate memory for a new stu structure in function readStu.");
fclose(fp);
return 0;
}
head = tail = p1;
tail->next = NULL;
while (!feof(fp))
{
p1 = (stu *)
malloc(LEN);
if (p1 == NULL)
{
printf(
"Fail to allocate memory for a new stu structure in function readStu.");
fclose(fp);
return 0;
}
if (!fread(p1,
sizeof(stu),
1, fp))
{
free(p1);
return head;
}
tail->next = p1;
tail = p1;
tail->next = NULL;
m_n++;
}
fclose(fp);
m_head = head;
return head;
}
——————————————
main.c
#include "final.h"
#include<math.h>
void showTitle()
{
printf(
"\n%-20s|%5s|%5s|score1|score2|score3|sum",
"name",
"ID",
"class",
"score1",
"score2",
"score3",
"sum");
}
void controller(
int flag)
{
int i =
0;
int a =
0;
stu *temp;
float var;
char name[
20];
switch (flag)
{
case 1:
if (m_head == NULL || m_head->next == NULL)
{
printf(
"\nNo student data.");
break;
}
temp = m_head;
printf(
"\ninput 0 to show all students' information");
printf(
"\nor input 1 and then an id or 2 and then a name to show one:");
scanf(
"%d", &a);
if (a ==
0)
{
showTitle();
while (temp->next)
{
showStu(temp->next);
temp = temp->next;
}
}
else
{
if (a ==
1)
{
printf(
"id:");
scanf(
"%d", &a);
if (a ==
0)
{
printf(
"\n0 is not an legal ID.");
break;
}
temp = findStu(m_head, a,NULL );
if (temp == NULL)
{
printf(
"\nNo such a student");
break;
}
showTitle();
showStu(temp->next);
}
else
{
if (a ==
2)
{
printf(
"name:");
fflush(stdin);
gets(name);
temp = findStu(m_head,
0, name);
if (temp == NULL)
{
printf(
"\nNo such a student");
break;
}
showTitle();
showStu(temp->next);
}
}
}
break;
case 2:
create();
break;
case 3:
if (m_head == NULL || m_head->next == NULL)
{
printf(
"\nNo student data.");
break;
}
temp = m_head;
printf(
"\ninput 1 and then an id or 2 and then a name to delete:");
scanf(
"%d", &a);
if (a ==
1)
{
printf(
"id:");
scanf(
"%d", &a);
if (a ==
0)
{
printf(
"\n0 is not an legal ID.");
break;
}
deleteStu(findStu(m_head, a, NULL));
}
else
{
if (a ==
2)
{
printf(
"name:");
fflush(stdin);
gets(name);
deleteStu(findStu(m_head,
0, name));
}
}
break;
case 4:
if (m_head == NULL || m_head->next == NULL)
{
printf(
"\nNo student data.");
break;
}
temp = m_head;
printf(
"\ninput 1 and then an id or 2 and then a name to update:");
scanf(
"%d", &a);
if (a ==
1)
{
printf(
"id:");
scanf(
"%d", &a);
updateStu(findStu(m_head, a, NULL)->next);
}
else
{
if (a ==
2)
{
printf(
"name:");
fflush(stdin);
gets(name);
updateStu(findStu(m_head,
0, name)->next);
}
}
break;
case 5:
if (m_head == NULL || m_head->next == NULL)
{
printf(
"\nNo student data.");
break;
}
var=varianceStu(m_head);
printf(
"average:%f,variance:%f,Standard Deviation:%f", m_ave,var,
sqrt(var));
break;
case 6:
exit(
0);
}
}
void printFunctionList()
{
printf(
"\n_____________________________________");
printf(
"\n1.print students' information");
printf(
"\n2.add a new student");
printf(
"\n3.delete a student");
printf(
"\n4.update a student");
printf(
"\n5.show the analysis of students' grade");
printf(
"\n6.exit");
printf(
"\nInput a number to choose function:");
}
void chooseFunction()
{
int flag =
0;
printFunctionList();
while (
scanf(
"%d", &flag))
{
if (flag <
1 && flag>
6)
{
printf(
"\nError!");
printFunctionList();
continue;
}
else
{
controller(flag);
printFunctionList();
}
}
}
int main()
{
m_head=readStu();
chooseFunction();
return 0;
}