程序设计综合实习(C语言):考勤管理系统_c语言创建一个职工考勤管理系统-程序员宅基地

技术标签: 算法  c语言  程序设计综合实习  链表  

一、目的

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;
	}
	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语言编程的基础知识,并学习了一些新的编程技能,对我的编程能力提高起到了积极的作用。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_74087709/article/details/130997287

智能推荐

while循环&CPU占用率高问题深入分析与解决方案_main函数使用while(1)循环cpu占用99-程序员宅基地

文章浏览阅读3.8k次,点赞9次,收藏28次。直接上一个工作中碰到的问题,另外一个系统开启多线程调用我这边的接口,然后我这边会开启多线程批量查询第三方接口并且返回给调用方。使用的是两三年前别人遗留下来的方法,放到线上后发现确实是可以正常取到结果,但是一旦调用,CPU占用就直接100%(部署环境是win server服务器)。因此查看了下相关的老代码并使用JProfiler查看发现是在某个while循环的时候有问题。具体项目代码就不贴了,类似于下面这段代码。​​​​​​while(flag) {//your code;}这里的flag._main函数使用while(1)循环cpu占用99

【无标题】jetbrains idea shift f6不生效_idea shift +f6快捷键不生效-程序员宅基地

文章浏览阅读347次。idea shift f6 快捷键无效_idea shift +f6快捷键不生效

node.js学习笔记之Node中的核心模块_node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是-程序员宅基地

文章浏览阅读135次。Ecmacript 中没有DOM 和 BOM核心模块Node为JavaScript提供了很多服务器级别,这些API绝大多数都被包装到了一个具名和核心模块中了,例如文件操作的 fs 核心模块 ,http服务构建的http 模块 path 路径操作模块 os 操作系统信息模块// 用来获取机器信息的var os = require('os')// 用来操作路径的var path = require('path')// 获取当前机器的 CPU 信息console.log(os.cpus._node模块中有很多核心模块,以下不属于核心模块,使用时需下载的是

数学建模【SPSS 下载-安装、方差分析与回归分析的SPSS实现(软件概述、方差分析、回归分析)】_化工数学模型数据回归软件-程序员宅基地

文章浏览阅读10w+次,点赞435次,收藏3.4k次。SPSS 22 下载安装过程7.6 方差分析与回归分析的SPSS实现7.6.1 SPSS软件概述1 SPSS版本与安装2 SPSS界面3 SPSS特点4 SPSS数据7.6.2 SPSS与方差分析1 单因素方差分析2 双因素方差分析7.6.3 SPSS与回归分析SPSS回归分析过程牙膏价格问题的回归分析_化工数学模型数据回归软件

利用hutool实现邮件发送功能_hutool发送邮件-程序员宅基地

文章浏览阅读7.5k次。如何利用hutool工具包实现邮件发送功能呢?1、首先引入hutool依赖<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.19</version></dependency>2、编写邮件发送工具类package com.pc.c..._hutool发送邮件

docker安装elasticsearch,elasticsearch-head,kibana,ik分词器_docker安装kibana连接elasticsearch并且elasticsearch有密码-程序员宅基地

文章浏览阅读867次,点赞2次,收藏2次。docker安装elasticsearch,elasticsearch-head,kibana,ik分词器安装方式基本有两种,一种是pull的方式,一种是Dockerfile的方式,由于pull的方式pull下来后还需配置许多东西且不便于复用,个人比较喜欢使用Dockerfile的方式所有docker支持的镜像基本都在https://hub.docker.com/docker的官网上能找到合..._docker安装kibana连接elasticsearch并且elasticsearch有密码

随便推点

Python 攻克移动开发失败!_beeware-程序员宅基地

文章浏览阅读1.3w次,点赞57次,收藏92次。整理 | 郑丽媛出品 | CSDN(ID:CSDNnews)近年来,随着机器学习的兴起,有一门编程语言逐渐变得火热——Python。得益于其针对机器学习提供了大量开源框架和第三方模块,内置..._beeware

Swift4.0_Timer 的基本使用_swift timer 暂停-程序员宅基地

文章浏览阅读7.9k次。//// ViewController.swift// Day_10_Timer//// Created by dongqiangfei on 2018/10/15.// Copyright 2018年 飞飞. All rights reserved.//import UIKitclass ViewController: UIViewController { ..._swift timer 暂停

元素三大等待-程序员宅基地

文章浏览阅读986次,点赞2次,收藏2次。1.硬性等待让当前线程暂停执行,应用场景:代码执行速度太快了,但是UI元素没有立马加载出来,造成两者不同步,这时候就可以让代码等待一下,再去执行找元素的动作线程休眠,强制等待 Thread.sleep(long mills)package com.example.demo;import org.junit.jupiter.api.Test;import org.openqa.selenium.By;import org.openqa.selenium.firefox.Firefox.._元素三大等待

Java软件工程师职位分析_java岗位分析-程序员宅基地

文章浏览阅读3k次,点赞4次,收藏14次。Java软件工程师职位分析_java岗位分析

Java:Unreachable code的解决方法_java unreachable code-程序员宅基地

文章浏览阅读2k次。Java:Unreachable code的解决方法_java unreachable code

标签data-*自定义属性值和根据data属性值查找对应标签_如何根据data-*属性获取对应的标签对象-程序员宅基地

文章浏览阅读1w次。1、html中设置标签data-*的值 标题 11111 222222、点击获取当前标签的data-url的值$('dd').on('click', function() { var urlVal = $(this).data('ur_如何根据data-*属性获取对应的标签对象

推荐文章

热门文章

相关标签