C语言项目实战——学生成绩系统管理

C语言项目实战 --学生成绩管理系统

项目开发基本流程
  • 可行性分析和项目开发计划
    技术可行性:软硬件、技术人员条件、项目是否能实现
    经济可行性:成本估算、开发时间、经济效益评估,看这个项目是否有开发价值
    社会可行性:审批、法律操作是否可行
  • 需求分析
    问题分析与识别
    • 功能需求:软件要具备和实现的功能
    • 性能需求:软件技术性能指标
    • 环境需求:软件运行需要额软硬件环境
      分析与综合,到处软件的逻辑模型:
      在分析与综合中,逐步细化软件模型,划分各个子功能采用图文混合的方式建立系统的逻辑模型
      编写文档
  • 概要设计
    设计软件及系统结构:
    经一个复杂的系统按功能进行模块划分,高内聚、低耦合。
    确定每个模块的功能混合模块之间的调用关系。
    确定模块之间的接口。
    数据结构及数据库设计:
    数据结构、模块接口之间通信的数据结构
    编写概要设计文档:
    测试计划、测试用例
  • 详细设计
    为每个模块进行详细的算法设计、处理过程使用算法描述出来
    模块内的数据结构设计与定义
    对数据库进行物理设计
    编写详细设计说明书
    使用伪代码来描述模块算法和细节处理
  • 编码
    在前一阶段的基础上,选择合适的语言进行物理实验
    • 程序语言设计的选择
      项目应用领域
      软件开发的方法
      软件执行的环境
      软件发开人员的知识储备
    • 程序设计风格
      源程序的编码规范
      数据说明(注释)
      效率
  • 测试
    • 测试的重要性
      测试原则与分类
    • 测试流程
      单元测试
      集成测试
      压力测试
      版本发布
      a阶段:Alpha测试,主要看有么有功能上的缺失或者系统上的大错误
      b阶段:Beta测试,给用户使用测试,Beta1–Beta2
      c阶段:Rc测试(release candidate)Rc1 --Rc2–Rc3 基本稳定版本,没有大的修改了
  • 软件发布、维护与运营

一、可行性分析及项目开发计划

可行性分析
  • 技术可行性:
    硬件:c高级语言,跟硬件平台无关,编写的程序可以在任何硬件平台运行
    软件:纯软件的业务逻辑操作,只依赖C标准库,软件上没有什么问题
    技术人员的要求:只要有c语言的基础
    综上所述,项目可以实现
  • 经济可行性:
  • 社会可行性:
    方便电子化管理、无纸化绿色低碳环保办公
项目开发计划
  • 时间进度安排
    资源安排
    人力
    软硬件资源
    经费
    成本风险评估

二、需求分析

问题分析与识别
  • 功能需求:
    实现学生信息的添加、删除、查询、修改等功能
    学生成绩的磁盘保存
    方便的人机交互功能
  • 性能需求:
    软件运行稳定
    速度快、效率高
    可移植性好,在不同的处理器的操作系统平台上都可以正常使用
    健壮性:对于出错处理完善
    人机交互友好,操作简单易用,容易上手
    扩展性好:采用模块化编程、添加删除新功能模块方便
分析与综合,导出软件的逻辑模型
  • 菜单人际交互
  • 存储模块
  • 成绩添加
  • 成绩删除
  • 成绩查询
  • 成绩打印
编写文档

《需求规格说明书》

三、概要设计

  • 学生成绩管理系统结构设计

模块划分
菜单及人机交互模块、成绩存储模块、成绩打印、成绩添加、成绩删除、成绩修改、成绩统计等

模块功能
void student_save();
void student_add();
void student_delete();
void student_print();
void student_tongji();
void student_modify();
void student_menu();

模块之间的调用关系:
菜单模块根据用户输入选择调用其他模块的函数,实现各种操作。
模块之间的接口:
结构体数组 :struct student stu[50];
数组的长度:int actual_len;
链表

  • 数据结构设计
    struct student
    {
    unsigned int no;
    char name[10];
    char sex;
    unsigned char age;
    float chinese;
    float english;
    float math;

}

  • 编写概要设计文档
    首先main函数里面通过主菜单模块,根据用户的输入,执行不同的操作;成绩添加、删除、查询、打印、保存等,每个模块功能通过每个模块定义的函数回来实现,具体的参数可以根据实际的需要动态修改,

程序运行时,首先从数据文件中读取学生信息,使用一个全局的结构体数组,来保存学生的信息,每个数组元素代表一个学生的信息,同事全局变量actual_len表示当前处理的学生人数,当进行添加、修改、删除等操作,学生人数和信息会动态发生变化,药剂师保存到磁盘文件中,与磁盘文件保持一致。

四、详细设计

  • 模块详细设计

  • 菜单及人机交互
    1:首先要打印菜单,提醒用户输入操作选项
    2:处理用户输入,根据用户选择调用不同的模块
    3:清屏,然后重新打印菜单,进入循环,再次提醒用户输入
    4:模块函数
    void student_save(int *len,struct student stu[]));
    void student_add(int *len,struct student stu[]));
    void student_delete(int *len,struct student stu[]));
    void student_print(int len,struct student stu[]));
    void student_tongji(int len,struct student stu[]));
    void student_modify(int len,struct student stu[]));
    void student_menu();

  • 成绩添加
    void student_add(int *len,struct student stu[])
    {
    首先我们要定义一个结构体变量:
    提醒用户输入学生信息:
    把这个结构体变量保存到数组中
    更新数组的实际长度:更新实际的学生人数
    刷新到文件中
    }

  • 成绩删除
    void student_delete(int *len,struct student stu[])
    {
    提示用户输入学生信息
    根据学号还是根据姓名
    找到这个变量在数组中的位置
    删除这个数组元素
    后边的数组元素迁移
    更改数组的当前实际长度
    刷新到文件中
    }

  • 成绩查询
    void student_find(int len,struct student stu[])
    {
    提醒用户根据学好还是根据姓名查找
    用户选择
    根据姓名或者学号找到在数组中的位置
    打印整个数组元素的信息
    }

  • 成绩修改
    void student_modify(int len,struct sstudent stu[])
    {
    提醒用户输入姓名或者学号
    根据姓名或者学号找到在数组中的位置
    提醒用户修改选项
    根据用户修改选项,提醒用户键入修改值
    将修改的数组元素保存到文件中

}

  • 成绩保存
    void student_save(int len ,struct student stu[])
    {
    以写的方式,打开当前的文件
    将数组元素逐个写入到文件
    关闭文件
    }

  • 成绩统计
    void student_tongji(int len,struct student stu[]))
    {
    逐个对数组元素进行计算

}

编码(1)

main.c
#include<stdio.h>
#include"student.h"

int actual_len = 0;
struct student stu[50];
struct student std[2] = {
	{1001,"Xun",'M',18,99,98,97},
	{1002,"Jan",'M',18,99,98,97},
};
int main() {

	student_menu();
	
}
void student_menu()
{

	while (1) {
		printf("---------------------------------------------------------------------------\n");
		printf("\t\t欢迎使用学生成绩管理系统\n");
		printf("\t1:成绩添加\t2:成绩删除\n");
		printf("\t3:成绩查询\t4:成绩修改\n");
		printf("\t5:成绩统计\t6:返主菜单\n");
		printf("---------------------------------------------------------------------------\n");

		int sec = 0;
		printf("请输入选项:");
		scanf("%d", &sec);
		switch (sec)
		{
		case 1:
			student_array_add(&actual_len, stu);
			break;
		case 2:
			student_array_delate(&actual_len, stu);
			break;
		case 3:
			student_find(actual_len, stu);
			break;
		case 4:
			student_modify(actual_len, stu);
			break;
		case 5:
			student_count(actual_len, stu);
		case 6:
			system("cls");

			student_menu();
		default:
			printf("输入错误!");

		}
}

}

int main01() {

#if  0//查看内存文件中的真实数据模块
	//storge
	printf("actual_len = %d\n", actual_len);
	student_array_init(&actual_len, stu);
	printf("actual_len = %d\n", actual_len);
	student_print(actual_len, stu);
#endif

#if 0  //保存与删除模块
	student_array_add(&actual_len, stu);
	//student_array_delate(&actual_len, stu);
#endif

#if 0
	 student_find(actual_len, stu);

#endif

#if 0
	 student_modify(actual_len, stu);

#endif
#if  0

	 student_count(actual_len, stu);

#endif // 


}
stduent.c
#include<stdio.h>
#include<string.h>
#include"student.h" 

void array_print(struct student stu)
{
	printf("学号\t姓名\t性别\t年龄\t语文\t\t英语\t\t数学\n");
	printf("%d\t%s\t%c\t%d\t%f\t%f\t%f\n", stu.no, stu.name, stu.sex, stu.age, stu.chinese, stu.english, stu.math);

}

void student_print(int len,struct student stu[])
{
	printf("学号\t姓名\t性别\t年龄\t语文\t\t英语\t\t数学\n");
	for(int i=0;i<len;i++)
	printf("%d\t%s\t%c\t%d\t%f\t%f\t%f\n",stu[i].no, stu[i].name, stu[i].sex, stu[i].age, stu[i].chinese, stu[i].english, stu[i].math);

}
int student_save(int len, struct student stu[])
{ 
	FILE * fp;
	if ((fp = fopen("student.dat","wb")) == NULL)
	{
		printf("文件打开失败!\n");
		return -1;
	}
	for (int i = 0; i < len; i++)
	{
		fwrite(&stu[i], sizeof(struct student), 1, fp);
		if (ferror(fp))
		{
			printf("数据写入失败!\n");
			return -2;
		}
	}
	
	fclose(fp);
	return 0;
}
int student_array_init(int *len,struct student stu[])
{
	FILE *fp;
	
	if ((fp = fopen("student.dat", "ab+"))== NULL)
	{
		printf("文件打开失败!\n");
		return -1;
	}
	int i = 0;
	fread(&stu[i], sizeof(struct student), 1, fp);
	
	
	while (!feof(fp))
	{
		i++;
		fread(&stu[i], sizeof(struct student), 1, fp);

		if (ferror(fp))
		{
			printf("数据读取失败!\n");
			return -2;
		}	
	}
	*len = i;
	fclose(fp);
	return 0;
}

int student_array_add(int* len, struct student stu[])
{
	struct student std;
	int num,i;
	printf("请输入要添加的学生信息人数:");
	scanf("%d", &num);
	for (i = 0; i < num; i++)
	{
		
		printf("请输入第%d个学生信息:\n",i+1);
		printf("学号<1000>:");
		scanf("%d", &std.no);
		printf("姓名:");
		scanf("%s", &std.name);
		rewind(stdin);
		printf("性别(M/F):");
		scanf("%c", &std.sex);	
		printf("年龄:");
		scanf("%d", &std.age);	
		printf("语文:");
		scanf("%f", &std.chinese);	
		printf("英语:");
		scanf("%f", &std.english);
		printf("数学:");
		scanf("%f", &std.math);
		stu[*len] = std;
		(*len)++;
	}
	student_save(*len, stu);
	student_print(*len, stu);
	return 0;
}

int stu_del_by_name(char name[], int* len, struct student stu[])
{
	
	int i = 0;
	for (i; i < *len; i++)
	{
		if (strcmp(name, stu[i].name) == 0)
		{
			break;
		}
	}
		if(i == *len)
		{
			printf("error:无法找到学生%s的信息!\n",name);
			return -1;
		}
	for (i; i < *len - 1; i++)
	{
		stu[i] = stu[i + 1];
		(*len)--;
		return 0;
	}
	return 0;
}

int stu_del_by_no(int no,int* len, struct student stu[])
{
	int i;
	for (i = 0; i < *len; i++)
	{
		if (stu[i].no == no)
			break;
	}
	if (i == *len)
	{
		printf("删除失败,无法找到学号 %d 的信息!\n", no);
		return -1;
	}
	for (i; i < *len - 1; i++)
		stu[i] = stu[i + 1];
	(*len)--;

	return 0;
}
int student_array_delate(int* len, struct student stu[])
{
	student_array_init(len, stu);
	student_print(*len, stu);
	int select;
	printf("------------------------------\n");
	printf("请选择查询删除的方式:\n");
	printf("1:根据学生姓名查找删除\n2:根据学生学号查找删除\n(1/2):");
	scanf("%d", &select);
	if (select == 1)
	{
		char name[20];
		printf("请输入要删除的学生姓名:");
		scanf("%s", name);
		stu_del_by_name( name, len, stu);

	}
	else if (select == 2)
	{
		 int no;
		printf("请输入要删除的学生学号");
		scanf("%d", &no);
			stu_del_by_no(no,len, stu);
	}
	else
	{
		printf("无效输入!\n");
		return -1;
	}

	student_save(*len, stu);
	student_print(*len, stu);

	return 0;
}

int stu_find_by_name(char name[], int  len, struct student stu[])
{
	int i;
	for (i=0; i < len; i++)
	{
		if (strcmp(name, stu[i].name) == 0)
			break;
	}
	
	if (i == len)
	{
		printf("error:无法找到学生%s的信息!\n", name);
		return -1;
	}

	printf("查找成功,该学生信息:\n");
	array_print(stu[i]);

	return 0;
}

int stu_find_by_no(int no, int len, struct student stu[])
{
	int i;
	for (i = 0; i < len; i++)
	{
		if (no == stu[i].no)
			break;
	}
	if (i == len)
	{
		printf("查询失败,无法找到学号%d的信息!\n", no);
		return -1;
	}
	printf("查找成功,该学生信息:\n");
	array_print(stu[i]);

	return 0;
}

int student_find(int len, struct student stu[])
{
	int select;
	printf("------------------------------\n");
	printf("请选择查询的方式:\n");
	printf("1:根据学生姓名查询\n2:根据学生学号查询\n(1/2):");
	scanf("%d", &select);
	if (select == 1)
	{
		char name[20];
		printf("请输入要查询的学生姓名:\n");
		scanf("%s", name);
		stu_find_by_name(name, len, stu);

	}
	else if (select == 2)
	{
		int no;
		printf("请输入要查询的学生学号:\n");
		scanf("%d", &no);
		stu_find_by_no(no, len, stu);
	}
	else
	{
		printf("无效输入!\n");
		return -1;
	}
	return 0;
}

int stu_modify_by_name(char name[], int len, struct student stu[])
{
	int i;
	for (i = 0; i < len; i++)
	{
		if (strcmp(name, stu[i].name) == 0)
			break;
	}

	if (i == len)
	{
		printf("error:无法找到学生%s的信息!\n", name);
		return -1;
	}

	array_print(stu[i]);
	printf("请输入需要修改的成员:\n");
	printf("1:修改学号\n2:修改姓名\n3:修改性别\n4:修改年龄\n5:修改语文\n6:修改英语\n7:修改数学");
	int num;
	scanf("%d", &num);
	switch (num)
	{
	case 1:
		printf("将学号修改为:");
		scanf("%d", &stu[i].no);
		break;
	case 2:
		printf("将姓名修改为:");
		scanf("%s", &stu[i].name);
		break;
	case 3:
		printf("将性别修改为:");
		scanf("%c", &stu[i].sex);
		break;
	case 4:
		printf("将年龄修改为:");
		scanf("%d", &stu[i].age);
		break;
	case 5:
		printf("将语文修改为:");
		scanf("%f", &stu[i].chinese);
		break;
	case 6:
		printf("将英语修改为:");
		scanf("%f", &stu[i].english);
		break;
	case 7:
		printf("将数学修改为:");
		scanf("%f", &stu[i].math);
		break;
	default:
		printf("输入错误!");
	}
	return 0;
}

int stu_modify_by_no(int no, int len, struct student stu[])
{
	int i;
	for (i = 0; i < len; i++)
	{
		if (no == stu[i].no)
			break;
	}
	if (i == len)
	{
		printf("查询失败,无法找到学号%d的信息!\n", no);
		return -1;
	}
	array_print(stu[i]);
	printf("请输入需要修改的成员:\n");
	printf("1:修改学号\n2:修改姓名\n3:修改性别\n4:修改年龄\n5:修改语文\n6:修改英语\n7:修改数学\n:");
	int num;
	scanf("%d", &num);
	switch (num)
	{
	case 1:
		printf("将学号修改为:");
		scanf("%d", &stu[i].no);
		break;
	case 2:
		printf("将姓名修改为:");
		scanf("%s", &stu[i].name);
		break;
	case 3:
		printf("将性别修改为:");
		scanf("%c", &stu[i].sex);
		break;
	case 4:
		printf("将年龄修改为:");
		scanf("%d", &stu[i].age);
		break;
	case 5:
		printf("将语文修改为:");
		scanf("%f", &stu[i].chinese);
		break;
	case 6:
		printf("将英语修改为:");
		scanf("%f", &stu[i].english);
		break;
	case 7:
		printf("将数学修改为:");
		scanf("%f", &stu[i].math);
		break;
	default:
		printf("输入错误!");
	}
	return 0;
}

int student_modify(int len, struct student stu[])
{
	int select;
	printf("------------------------------\n");
	printf("请选择查找修改的方式:\n");
	printf("1:根据学生姓名查找修改\n2:根据学生学号查找修改\n(1/2):");
	scanf("%d", &select);
	if (select == 1)
	{
		char name[20];
		printf("请输入要修改的学生姓名:\n");
		scanf("%s", name);
		stu_modify_by_name(name, len, stu);

	}
	else if (select == 2)
	{
		int no;
		printf("请输入要修改的学生学号:\n");
		scanf("%d", &no);
		stu_modify_by_no(no, len, stu);
	}
	else
	{
		printf("无效输入!\n");
		return -1;
	}
	student_save(len, stu);
	student_print(len, stu);
	return 0;
}

int student_count(int len, struct student stu[])
{
	student_array_init(&len, stu);
	float  chinese_avr = 0, english_avr = 0, math_avr = 0;
	int chinese_fail = 0, english_fail = 0, math_fail = 0;

	for (int i = 0; i < len ;i++)
	{
		chinese_avr += stu[i].chinese;
		english_avr += stu[i].english;
		math_avr += stu[i].math;
	}
	
	chinese_avr /= len;
	english_avr /= len;
	math_avr    /= len;

	for (int i = 0; i < len; i++)

	{
		if (stu[i].chinese < 60)
			chinese_fail++;
		if (stu[i].english < 60)
			english_fail++;
		if (stu[i].math < 60)
			math_fail++;
	}
	printf("------------------------------------------------------------------\n");
	printf("语文平均成绩为:%f\n英语平均成绩为:%f\n数学平均成绩为:%f\n", chinese_avr, english_avr, math_avr);
	printf("------------------------------------------------------------------\n");
	printf("语文不及格人数为:%d\n", chinese_fail);
	printf("英语不及格人数为:%d\n", english_fail);
	printf("数学不及格人数为:%d\n", math_fail);
	printf("------------------------------------------------------------------\n");

	return 1;
}


stduent.h
#pragma once
#ifndef __STUDENT_H__
#define __STUDENT_H__
struct student {
	unsigned int no;
	char name[10];
	char sex;
	int age;
	float chinese;
	float english;
	float math;
};

void array_print(struct student stu);        //一种简单的结构体打印方式,直接传结构体名称(首地址)就能打印
void student_print(int len, struct student stu[]);//结构体数组打印,第一个参数是结构体数组长度,第二个参数是结构体数组的地址
int student_save(int len, struct student stu[]);//把结构体数组保存到文件中
int student_array_init(int* len, struct student stu[]);//把文件中的结构体数组读取到stu[]
int student_array_add(int* len, struct student stu[]);//向文件中添加结构体数组

int student_array_delate(int* len, struct student stu[]);//1:删除文件中的一个结构体数组
int stu_del_by_no(int no,int *len, struct student stu[]);//2:按照学号删除文件中的一个结构体数组(属于1中的一个小函数)
int stu_del_by_name(char name[], int* len, struct student stu[]);//3:按照姓名删除文件中的一个结构体数组(属于1中的一个小函数)

int student_find(int len, struct student stu[]);//查询文件中的结构体,
int stu_find_by_name(char name[], int len, struct student stu[]);
int stu_find_by_no(int no, int len, struct student stu[]);

int student_modify(int len, struct student stu[]);
int stu_modify_by_name(char name[],int len,struct student stu[]);
int stu_modify_by_no(int no, int len, struct student stu[]);

int student_count(int len, struct student stu[]);

void student_menu();

#endif		


  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值