程序设计综合实习(C语言):考勤管理系统

news2024/11/25 4:21:14

一、目的

1.调动创新能力的培养

二、实习环境

Visual Studio 2022

三、实习内容与步骤

问题描述:

每个员工信息包括工号、姓名、年龄、性别、部门等;

功能要求:

(1)能够增加、删除、修改员工信息。

(2)提示开始考勤后,以录入一个员工号后敲回车表明该员工考勤一次;

(3)输出功能:能够输出员工信息;

(4)查找功能:能够查询员工信息和考勤信息;

(5)统计功能:能够对考勤进行统计。

(6)要求能通过文件保存信息,程序支持信息导入和保存 

四、程序流程图、算法及运行结果

流程图

算法描述

1.定义员工信息的结构体,包括工号、姓名、年龄、性别、部门、考勤次数和出勤次数。同时定义链表的头指针和尾指针。
2.实现菜单功能,包括增加员工信息、删除员工信息、修改员工信息、开始考勤、输出员工信息、查找员工信息和考勤信息、统计员工出勤率和退出系统。
3.实现增加员工信息的功能,包括输入员工的工号、姓名、年龄、性别、部门等信息,并将其插入到链表的尾部。同时需要保存新增的员工信息到文件中。
4.实现删除员工信息的功能,先输入需要删除的员工工号,然后遍历链表,找到对应的员工信息并删除。同时需要保存删除后的员工信息到文件中。
5.实现修改员工信息的功能,先输入需要修改的员工工号,然后选择需要修改的信息,最后将修改后的信息保存。同时需要保存修改后的员工信息到文件中。
6.实现输出员工信息的功能,遍历链表,将所有员工信息输出。
7.实现查找员工信息和考勤信息的功能,可以根据员工的工号或姓名进行查找。找到对应的员工信息后,将其输出。
8.实现开始考勤的功能,输入员工工号和考勤状态,对应员工的考勤次数加1,出勤次数加1或不变。输入0停止考勤,同时需要保存考勤后的员工信息到文件中。
9.实现统计员工出勤率的功能,遍历链表,计算每个员工的出勤率,并输出。
10.实现导入和保存员工信息的功能,通过文件操作实现。在程序启动时,从文件中读取员工信息并存入链表中;在程序结束时,将链表中的员工信息保存到文件中。

程序代码: 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct worker {
	int num;//工号
	char name[100];//姓名
	int age;//年龄
	char sex[100];//性别
	char department[100];//部门
	struct worker* next;
	int attendence;//考勤次数
	int chuqin;//出勤次数
};
int num;//工号
char name[100];//姓名
int age;//年龄
char sex[100];//性别
char department[100];//部门
int cnt;
int op;
int flag;
int st;
int attendence;//考勤次数
int chuqin;//出勤次数
FILE* fp;
struct worker* p, * q, * head = NULL, * tail = NULL;
void menu();//菜单
void add();//增加信息
void delete1();//删除信息
void modify();//修改信息
void output();//输出信息
void search();//查找员工信息和考勤信息
void attendstart();//开始考勤
void attendstatistics();//统计考勤
void read_in_information();//导入信息
void save_information();//保存信息
int main()
{
	read_in_information();//导入信息
	st = 1;
	while (1) {
		menu();//菜单
		scanf("%d", &op);
		if (op >= 1 && op <= 8) {
			switch (op) {
			case 1:add(); break;
			case 2:delete1(); break;
			case 3:modify(); break;
			case 4:attendstart(); break;
			case 5:output(); break;
			case 6:search(); break;
			case 7:attendstatistics(); break;
			case 8:st = 0; break;
			}
		}
		else printf("输入无效\n");
		if (st == 0) break;
	}
	return 0;
}
//菜单
void menu() {
	printf("                                            考勤管理系统\n");
	printf("***********************************************************************************************************************\n");
	printf("                                 1.增加员工信息(工号,姓名,年龄,性别,部门)\n");
	printf("                                 2.删除员工信息(根据员工工号删除)\n");
	printf("                                 3.修改员工信息(根据工号修改该员工信息)\n");
	printf("                                 4.开始考勤\n");
	printf("                                 5.输出员工信息\n");
	printf("                                 6.查找员工信息和考勤信息\n");
	printf("                                 7.统计员工出勤率\n");
	printf("                                 8.退出\n");
	printf("***********************************************************************************************************************\n");
	printf("请输入代码选择(1-8):");
}
//增加员工信息
void add() {
	printf("请输入需要增加的员工信息(工号,姓名,年龄,性别,部门):\n");
	scanf("%d%s%d%s%s", &num, name, &age, sex, department);
		p = (struct worker*)malloc(sizeof(struct worker));
		if (p != NULL) {
			p->num = num;
			strcpy(p->name, name);
			p->age = age;
			strcpy(p->sex, sex);
			strcpy(p->department, department);
			p->attendence = 0;
			p->chuqin = 0;
			p->next = NULL;
		}
		if (head == NULL) {
			head = p;
			tail = p;
		}
		else {
			tail->next = p;
			tail = p;
		}
	save_information();
}
//删除员工信息
void delete1() {
	printf("请输入需要删除的员工的工号:\n");
	scanf("%d", &num);
	p = head;
	q = head;
	cnt = 0;
	while (p != NULL) {
		if (p->num == num) break;
		q = p;
		cnt++;
		p = p->next;
	}
	if (p != NULL) {
        printf("删除成功!!!\n");
		if (cnt == 0) head = p->next;
		else q->next = p->next;
	}
	else printf("没有查到该员工工号!!!\n");
	save_information();
}
//修改员工信息
void modify() {
	p = head;
	printf("请输入需要修改的员工的工号:\n");
	scanf("%d", &num);
	while (p != NULL) {
		if (p->num == num) break;
		p = p->next;
	}
	printf("请输入需要修改的信息:\n");
	printf("按1:修改工号 "); printf("按2:修改姓名 "); printf("按3:修改年龄 ");
	printf("按4:修改性别 "); printf("按5:修改部门 "); printf("按6:停止修改 ");
	printf("\n请按键:");
	scanf("%d", &op);
	flag = 1;
	while (1) {
		if (op >= 1 && op <= 6) {
			switch (op)
			{
			case 1:printf("请输入工号:"); scanf("%d", &num); p->num = num; break;
			case 2:printf("请输入姓名:"); scanf("%s", name); strcpy(p->name, name); break;
			case 3:printf("请输入年龄:"); scanf("%d", &age); p->age = age; break;
			case 4:printf("请输入性别:"); scanf("%s", sex); strcpy(p->sex, sex); break;
			case 5:printf("请输入部门:"); scanf("%s", department); strcpy(p->department, department); break;
			case 6:flag = 0; break;
			}
		}
		else printf("按键无效,请重新输入:\n");
		if (flag == 0) break;
		printf("请输入需要修改的信息:\n");
		printf("按1:修改工号 "); printf("按2:修改姓名 "); printf("按3:修改年龄 ");
		printf("按4:修改性别 "); printf("按5:修改部门 "); printf("按6:停止修改 ");
		printf("\n请按键:");
		scanf("%d", &op);
	}
	save_information();
}
//输出员工信息
void output() {
	printf("输出所有员工信息:\n");
	printf("工号 姓名 年龄  性别     部门  考勤次数  出勤次数\n");
	p = head;
	while (p != NULL) {
		printf("%d%4s%5d   %-10s%2s%7d%9d\n", p->num, p->name, p->age, p->sex, p->department, p->attendence,p->chuqin);
		p = p->next;
	}
save_information();
}
//查找员工信息和考勤信息
void search() {
	flag = 1;
	while (1)
	{
		printf("请输入需要查找的员工工号或姓名\n按键1选择输入工号,按键2选择输入姓名,按键0选择停止输入:");
		scanf("%d", &op);
		if (op == 1 || op == 2 || op == 0) {
			switch (op)
			{
			case 0:flag = 0; break;
			case 1:
			{printf("请输入要查找的工号:");
			scanf("%d", &num);
			p = head;
			while (p != NULL) {
				if (p->num == num) break;
				p = p->next;
			}
			printf("该员工信息如下:\n");
			printf("工号 姓名 年龄  性别     部门  考勤次数  出勤次数\n");
			printf("%d%4s%5d   %-10s%2s%7d%9d\n", p->num, p->name, p->age, p->sex, p->department, p->attendence,p->chuqin);
			}
			break;
			case 2:
			{
				printf("请输入要查找的姓名:");
				scanf("%s", name);
				p = head;
				while (p != NULL) {
					if (strcmp(p->name, name) == 0) break;
					p = p->next;
				}
			}
			printf("该员工信息如下:\n");
			printf("工号 姓名 年龄  性别     部门  考勤次数  出勤次数\n");
			printf("%d%4s%5d   %-10s%2s%7d%9d\n", p->num, p->name, p->age, p->sex, p->department, p->attendence,p->chuqin);
			break;
			}
		}
		else {
			printf("输入无效,请重新输入\n");
			continue;
		}
		if (flag == 0) break;
	}
}
//开始考勤
void attendstart() {
	printf("开始考勤!!!\n");
	printf("请输入工号(输入0停止考勤),考勤状态(0表示缺勤,1表示出勤):");
	scanf("%d%d", &num,&chuqin);
	while (1) {
		if (num == 0) return;
		p = head;
		while (p != NULL) {
			if (p->num == num) break;
			p = p->next;
		}
		if (p == NULL) printf("没有找到该员工!!!\n");
		else {
			printf("%s考勤成功\n", p->name);
			p->attendence++;
		}
		if (chuqin == 1) p->chuqin++;
		printf("请输入工号(输入0停止考勤),考勤状态(0表示缺勤,1表示出勤):");
		scanf("%d%d", &num, &chuqin);
	}
	save_information();
}
//统计员工出勤率
void attendstatistics() {
	p = head;
	while (p != NULL) {
		if(p->attendence!=0) printf("工号:%d 姓名:%s 出勤率:%.0f%%\n",p->num,p->name,(double)(p->chuqin)/p->attendence*100);
		else printf("工号:%d 姓名:%s 出勤率:0%%\n", p->num, p->name);
		p = p->next;
	}
}
//导入信息
void read_in_information() {
	if ((fp = fopen("D:\\data.txt", "r")) == NULL) {
		printf("file open error!\n");
		exit(0);
	}
	while (!feof(fp)) {
		p = (struct worker*)malloc(sizeof(struct worker));
		if (p != NULL) {
			fscanf(fp, "%d%s%d%s%s%d%d", &p->num, p->name, &p->age, p->sex, p->department, &p->attendence,&p->chuqin);
			p->next = NULL;
		}
		if (head == NULL) {
			head = p;
			tail= p;
		}
		else {
			tail->next = p;
			tail = p;
		}
	}
	if (fclose(fp)) {
		printf("can not close the file!\n");
		exit(0);
	}
}
//保存信息
void save_information() {
	if ((fp = fopen("D:\\data.txt", "w")) == NULL) {
		printf("file open error!\n");
		exit(0);
	}
	p = head;
while (p != NULL) {
		if(p->next!=NULL) fprintf(fp, "%d %s %d %s %s %d %d\n", p->num, p->name, p->age, p->sex, p->department, p->attendence, p->chuqin);
		else fprintf(fp, "%d %s %d %s %s %d %d", p->num, p->name, p->age, p->sex, p->department, p->attendence, p->chuqin);
		p = p->next;
	}		p = p->next;
	}
	if (fclose(fp)) {
		printf("can not close the file!\n");
		exit(0);
	}
}

运行结果

 

 

  

五、知识点、难点及解决办法。

知识点

1.结构体:定义了一个名为worker的结构体,包含员工的基本信息(工号、姓名、年龄、性别、部门)、考勤次数和出勤次数。在增加、删除、修改、查询、统计 等功能中,都用到了worker结构体。
2.文件操作:通过read_in_information函数从文件中读取已有的员工信息并导入到程序中,在save_information函数中将程序中的员工信息保存到文件中。文件路径为D\\:data.txt,
3.链表:通过定义指针p、q、head和tail以链表的形式存储和管理员工信息,每个节点即为一个worker结构体。在增加、删除和输出员工信息等操作中,需要遍历整 个链表。
4.菜单设计:通过menu函数设计了一个菜单,让用户选择需要进行的操作。
5.操作实现:实现了增加员工信息、删除员工信息、修改员工信息、开始考勤、输出员工信息、查找员工信息和考勤信息、统计员工出勤率等基本操作。其中开始考勤和统计员工出勤率是根据考勤次数和出勤次数来计算的。

难点及解决办法

该程序的难点在于需要涉及到链表的操作和文件的读写,需要处理好相关的指针、数据结构和文件流等内容。
对于链表的操作,在增加、删除和修改等功能中,需要注意指针的移动、重新连接等细节。同时,链表操作需要考虑多种情况,如空链表、只有一个节点的链表、需要删除头节点等情况。对于文件的读写,需要注意文件流的打开和关闭、读取和写入的格式、文件路径的设置等问题。在程序中,相关操作需要判断文件是否成功打开或关闭,并检查文件读写操作是否成功。
解决办法可以采用编写函数来处理错表操作和文件读写,将不同功能的代码块分离开来,方便处理。在实现时,可以先使用伪代码或流程图来规划程序结构,再逐步实现各个模块的功能,最后进行测试和调试,确保程序正确运行。

六、编程小结或体会。

该程序是一个考勤管理系统,实现了员工信息的增加、删除、修改、输出、查找和考勤统计等功能。其中员工信息以链表形式存储,考勤信息则直接在员工结构体中记录。程序还实现了数据的持久化,即将员工信息保存在文件中,并在程序启动时从文件中读取已有的员工信息。通过编写该程序,我学会了如何使用链表来存储和管理数据,以及如何进行文件的读写操作。同时,我也意识到了数据的特久化对于一些需要长期保存的应用程序非常重要,可以保证数据不因程序的退出而丢失。此外,在编写程序过程中,我也加强了对于函数的使用和调用的理解,通过将各种功能拆分成不同的函数实现,使得程序结构更加清晰,易于维护和扩展。总之,通过编写这个考勤管理系统,我进一步巩固了C语言编程的基础知识,并学习了一些新的编程技能,对我的编程能力提高起到了积极的作用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/599247.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[CTFTraining] ASIS CTF 2019 Quals Unicorn shop

​ 我们随便买一件商品&#xff0c;1~3都显示&#xff1a; ​ 只有第4个显示&#xff1a; ​ 只允许输入一个字符&#xff0c;题目叫Unicorn&#xff0c;猜测为Unicode。在Unicode - Compart搜索比千大的Unicode码&#xff1a; ​ 最后填进去买下商品得到flag。 另外&#…

CDGA 认证:第四章 数据架构(重点章节)习题集解析

1. 企业架构不包括哪项&#xff1f;&#xff08; &#xff09; A 业务架构 B 数据架构 C 系统架构 D 技术架构 【答案解析】DAMA-DMBOK2 P72 2. 关于架构设计生命周期描述错误的是&#xff1f;( ) A 可以是针对当前的 B 可以是面向未来的 C 可以是已实施完成的 D 可以是已经…

Flutter 对话框【代码实践】

Flutter 对话框【代码实践】 文章目录 Flutter 对话框【代码实践】一、普通对话框1、示例一&#xff1a;圆角、背景截图代码 一、普通对话框 1、示例一&#xff1a;圆角、背景 截图 代码 Center(child: ElevatedButton(onPressed: () {showDialog(context: context,builder:…

Spring Boot如何实现分布式系统中的服务发现和注册?

Spring Boot如何实现分布式系统中的服务发现和注册&#xff1f; 随着互联网的快速发展&#xff0c;越来越多的企业开始将自己的业务迁移到分布式系统中。在这种情况下&#xff0c;服务发现和注册变得尤为重要。对于分布式系统中的每个服务来说&#xff0c;它需要知道其他服务的…

数据可视化——使用echars图表展示

目录 1、前言 2、解决方案 2.1、echars&#xff08;前端等组件库&#xff09; 2.2、PPT等其他软件工具 2.3、使用flourish等在线数据可视化制作平台 2.4、自己用代码实现 1、前言 有一个小作业&#xff0c;需要自己收集一组数据&#xff0c;然后进行数据可视化&#xff0…

QListWidget和QListView的使用和item点击事件

QListWidget和QListView很常用&#xff0c;但是使用上功能类似&#xff0c;往往容易分不清区别&#xff0c;但是不知道如何选择。这里总结下二者之间的区别和使用&#xff0c;分享给有需要的人&#xff0c;有需要的可点击收藏。 QListView介绍 QListView是Qt中用于显示列表的一…

程序在内存中的分布

1. 具体分布细节由编译器决定 2. 分布图 3. 静态局部变量通常被存放在程序的.data段中。 一般地&#xff0c;静态局部变量定义在函数体内&#xff0c;在函数执行时&#xff0c;它会在静态存储区分配内存&#xff0c;并且只被初始化一次。因为静态局部变量是在编译阶段产生的&…

SpringCloud GateWay 学习

SpringCloud GateWay 文章目录 SpringCloud GateWay1 Gateway 介绍2 代码实现 1 Gateway 介绍 有一个前后端分离项目&#xff0c;分析如图 使用网关服务Gateway&#xff0c;重构项目架构 Gateway 是在 Spring 生态系统之上构建的 API 网关服务&#xff0c;基于 Spring &#x…

DES,RAS,HASH

是猫咪&#xff0c;我加入了一些猫咪 1.DES Data Encryption Standard&#xff0c;即数据加密标准&#xff0c;是一种使用密钥加密的块算法。设计中使用了分组密码设计的两个原则&#xff1a;混淆&#xff08;confusion&#xff09;和扩散(diffusion)。DES加密算法原理简析_51…

秋招笔试零基础怎么办?自顶向下真题学习法,这样准备就稳啦!

秋招笔试零基础怎么办&#xff1f;自顶向下真题学习法&#xff0c;这样准备就稳啦 秋招临近&#xff0c;是时候提前准备笔试了。想必各位都忙着刷穿leetcode的剑指Offer&#xff0c;或者牛客的往年真题等等 但你真的了解自己的算法知识板块哪里有纰漏吗&#xff1f; 你知道今…

【C++】初识STL

目录 &#x1f31e;专栏导读 &#x1f31b;什么是STL &#x1f31b;STL的版本 &#x1f31b;STL的六大组件 &#x1f31b;STL的重要性 &#x1f31b;STL的缺陷 &#x1f31e;专栏导读 &#x1f31f;作者简介&#xff1a;日出等日落&#xff0c;在读本科生一枚&#xff0…

nginx网站安装服务

nginx概述 一款高性能、轻量级web服务软件稳定性高系统资源消耗低对HTTP并发连接的处理能力高单台物理服务器可支持30000~50000个并发请求 正向代理&#xff1a;通过代理服务器来访问资源&#xff0c;这种代理服务成为正向代理 反向代理&#xff1a;客户端与代理是无感知的&…

【Go LeetDay】总目录(1~83)

Leetcode Golang Day1~10 Golang每日一练(leetDay0001) 1. 两数之和 Two Sum 2. 两数相加 Add Two Numbers 3. 无重复字符的最长子串 Longest-substring-without-repeating-characters Golang每日一练(leetDay0002) 4. 寻找两个正序数组的中位数 Median of two sorted arra…

如何通过帮助文档来减少你的客服咨询量,提高工作效率

相信你的公司网站或者产品中总会设置一个“联系我们”按钮&#xff0c;让客户能够遇到问题随时能够找到客服人员并且快速解决&#xff0c;在创业初期&#xff0c;可能这样的模式没有问题&#xff0c;但是随着客户越来越多&#xff0c;客服的需求也随之增加&#xff0c;客服人员…

【iOS】--对象的底层结构

源码 先转一下源码 //#import <Foundation/Foundation.h> #import <objc/runtime.h>interface LGPerson : NSObject property (nonatomic, strong) NSString *KCName; endimplementation LGPersonendint main(int argc, const char * argv[]) {autoreleasepool {…

DVWA-XSS (Stored) Low/Medium/High低中高级别

「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 XSS Stroed 一、Low级别二、Medium级别三、Hign级别 这关是一个论坛功能&#xff0c;把用…

设计模式(六):结构型之代理模式

设计模式系列文章 设计模式(一)&#xff1a;创建型之单例模式 设计模式(二、三)&#xff1a;创建型之工厂方法和抽象工厂模式 设计模式(四)&#xff1a;创建型之原型模式 设计模式(五)&#xff1a;创建型之建造者模式 设计模式(六)&#xff1a;结构型之代理模式 目录 一、…

深入分析——Linux DMA Fence

目录 一 简介 二 基本原理 三 代码实现 3.1 Init 3.2 wait 3.3 signaling 3.4 callback 3.5 signaled 3.6 signal 3.7 refcount & release 四 Fence Status 一 简介 dma-fence是linux 内核中同步原语&#xff0c;它只有两种状态signaled和unsigned。因为其本身的…

华为OD机试之找出经过特定点的路径长度(Java源码)

找出经过特定点的路径长度 题目描述 无 输入描述 输入一个字符串&#xff0c;都是以大写字母组成&#xff0c;每个相邻的距离是 1&#xff0c; 第二行输入一个字符串&#xff0c;表示必过的点。 说明每个点可过多次。 输出描述 经过这些必过点的最小距离是多少 用例 输入 ANT…

OpenGL之坐标系统

文章目录 概述局部空间世界空间观察空间裁剪空间正射投影透视投影 进入3D代码 OpenGL希望在每次顶点着色器运行后&#xff0c;我们可见的所有顶点都为标准化设备坐标(Normalized Device Coordinate, NDC)。也就是说&#xff0c;每个顶点的x&#xff0c;y&#xff0c;z坐标都应该…