大作业:冬奥会志愿者信息管理系统

 本作业要求稍显奇葩,要求所有操作都必须在.txt文本文件中进行,如下:

 本次作业遇到的主要难题是FILE.eof()函数对文件的处理,如下:

运行过程中发现while进入了死循环。仔细勘察后发现,应该是FILE.get()读取了文本中的‘1’,导致FILE无法读取到任何数字字符 并传入num,导致FILE的文件指针不向后偏移,故而FILE.eof()始终为假,从而陷入死循环!

所以数字和文字混合读取时需要小心!

     

admin.cpp

​
​
#include<iostream>
#include<fstream>
#include"admin.h"
using namespace std;
using namespace adfile;
int main()
{
	int cho;//菜单选项
	int ID;//查找或删除的ID
	admin_inf oper;
	admin_inf::person* head;
	head = oper.input("input.txt");//读取input.txt的信息,并创建链表,返回头节点
	oper.input("menu.txt", cho);//读取菜单选项
	if ( cho == 1)//查找
	{
		oper.input("find.txt",ID);//修改ID
		oper.find(head, ID);
		system("C:\\Users\\jiangyuxuan\\source\\repos\\冬奥会志愿者信息管理系统\\冬奥会志愿者信息管理系统\\out.txt");//直接弹出文件页面
	}
	else if (cho == 2)//添加
	{
		admin_inf::person* new_guys = oper.input("insert.txt", head);//链表末尾新加入了内容,用于在out.txt中显示;
		oper.append(head,new_guys);//append()用于往input.txt中加入信息
		oper.output(head,"out.txt");//将信息输出到out.txt
		system("C:\\Users\\jiangyuxuan\\source\\repos\\冬奥会志愿者信息管理系统\\冬奥会志愿者信息管理系统\\out.txt");
	}
	else//删除
	{
		oper.input("find.txt", ID);//查ID;
		admin_inf::person* new_head = oper.del(head, ID);//删除节点后返回新链表
		oper.output(new_head, "out.txt");//输出新链表
		system("C:\\Users\\jiangyuxuan\\source\\repos\\冬奥会志愿者信息管理系统\\冬奥会志愿者信息管理系统\\out.txt");

	}
	
}

​

​

admin.h

#ifndef ADMIN
#define ADMIN
namespace adfile
{
	class admin_inf
	{
	public:
		struct person
		{
			int ID;
			char name[20];
			char sex;
			double score;
			int age;
			char language[10];
			struct person* next;
		};
	public:
		person* input(const char* file_name);//读取 input 文件并创建链表
		person* input(const char* fileName, person* q);//读取 insert 文件,并添加至链表末尾,返回新增人员的头节点,便于append
		void input(const char* fileName, int& num);//读取 menu 文件或 find 文件
		void output(person* head, const char* fileName);//将链表内容写入out.txt文件
		void find(person* head, int ID);//查找 Id 为 no 的人员,并返回该结点前一结点便于删除函数调用
		person* del(person* head, int ID);//从链表中删除 Id 为 no 的人员,返回链首
		void append(person* head, person* s);//插入一名人员至链尾,返回链首

	};
}

#endif // !ADMIN

admin_def.cpp

#include<iostream>
#include<fstream>
#include"admin.h"
using namespace std;
using namespace adfile;


admin_inf::person* admin_inf::input(const char* file_name)  //务必在函数名前加上admin_inf::!!!否则当外部函数处理!极易错沃日
{
	ifstream  rFILE("input.txt", ios::in);//使用构造函数以只读模式打开文件
	ofstream wFILE("out.txt", ios::out);//使用构造函数以写入模式打开文件
	if (!rFILE)
	{
		wFILE << "打开" << file_name << "文件失败!";
		wFILE.close();
		exit(1);
	}
		admin_inf::person* head = new admin_inf::person;//创建头节点,不存放数据,方便删除第一个人的信息
		head->next = NULL;
		admin_inf::person* temp = head;
		if (rFILE.peek()==EOF)
		{
			wFILE.close();
			return head;//input中没有内容,返回头节点
		}
		while (1)
		{
			admin_inf::person* node = new admin_inf::person;//创建节点
			rFILE >> node->ID >> node->name >> node->age
				>> node->sex >> node->language >> node->score;
			head->next = node;   
			head = node;
			rFILE.get();           			//惊天大bug!eof()函数读取的是文件中最后一个字符的下一个字符(文件结束符0xFF)!所以会在末尾读两次!!!导致多建一个尾节点
			if (rFILE.peek() == EOF)			   //所以这里必须要get(),将\n吃掉!这样才能直接读取文件结束符!md裂了,具体见本函数下面的链接
				break;                       //补更:对于有换行的文本文件,get()搭配peek()使用更方便,去nm的eof();
		}
		wFILE.close();
		rFILE.close();
		head->next = NULL;
		return temp;//返回头节点
}
	/*
	https:
	//blog.csdn.net/AllanZeng/article/details/4146223?spm=1001.2101.3001.6661.1&utm
	_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRL
	IST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edef
	ault%7ECTRLIST%7Edefault-1.no_search_link
	*/

void admin_inf::input(const char* file_name, int& num)//读取 menu 文件或 find 文件
{
	ifstream  rFILE(file_name, ios::in);
	ofstream wFILE("out.txt", ios::out);
	if (!rFILE)
	{
		wFILE << "文件中未检测到文本!";
		wFILE.close();
		exit(1);
	}
	else
	{
		if (rFILE.peek()==EOF)
		{
			wFILE << "find.txt文件中未检测到文本!";
			wFILE.close();
			exit(0);
		}
		else
		{
			rFILE >> num;
			rFILE.close();
			wFILE.close();
		}
	}
}

void admin_inf::find(admin_inf::person* head, int id)//查找 Id 为 no 的人员
{
	ofstream wFILE("out.txt", ios::out);
	admin_inf::person* temp = head->next;
	while (temp!=NULL&&temp->ID!=id)
		temp = temp->next;
	if (temp == NULL)
	{
		wFILE << "无此ID,请重新查找!";
		wFILE.close();
		exit(0);
	}
	wFILE << temp->ID << " " << temp->name << " " << temp->age << " " << temp->sex << " " << temp->language << " " << temp->score << endl;

}

admin_inf::person* admin_inf::input(const char* file_name, admin_inf::person* head)//读取 insert 文件,并添加至链表末尾
{
	ifstream rFILE(file_name, ios::in);
	ofstream wFILE("out.txt", ios::out);
	if (rFILE.peek()==EOF)  
	{
		wFILE << file_name << "文件中未检测到文本!";
		wFILE.close();
		exit(0);
	}
	admin_inf::person* new_head = new admin_inf::person;
	new_head->next = NULL;
	admin_inf::person* temp = new_head;
	rFILE >> new_head->ID >> new_head->name >> new_head->age >> new_head->sex
		>> new_head->language >> new_head->score;
	while (1)
	{
		rFILE.get();
		if (rFILE.peek() == EOF)  //这三行必须放前面
			break;
		admin_inf::person* new_one = new admin_inf::person;
		new_one->next = NULL;
		rFILE >> new_one->ID >> new_one->name >> new_one->age >> new_one->sex
			>> new_one->language >> new_one->score;
		new_head->next = new_one;
		new_head = new_one;
		
	}
	rFILE.close();
	while (head!=NULL && head->next != NULL)
		head = head->next;
	head->next = temp;
	return temp;
	
}

void admin_inf::output(admin_inf::person* head, const char* file_name)//将链表内容写入文件
{
	ofstream wFILE(file_name, ios::out);
	admin_inf::person* temp = head->next;
	if (temp == NULL)
	{
		wFILE << "无人员信息!";
		wFILE.close();
		exit(0);
	}
	while (temp)
	{
		wFILE << temp->ID << " " << temp->name << " " << temp->age << " " << temp->sex << " " << temp->language << " " << temp->score << endl;
		temp = temp->next;
	}
	wFILE.close();
}

admin_inf::person* admin_inf::del(admin_inf::person* head, int id)//从链表中删除 Id 为 no 的人员,返回链首
{                            
	ofstream wiFILE("input.txt", ios::out);
	ofstream woFILE("out.txt", ios::out);
	admin_inf::person* temp = head;
	admin_inf::person* Temp;
	while (temp->next!=NULL && temp->next->ID != id)
		temp = temp->next;
	if (temp->next == NULL)
	{
		woFILE << "没有此ID信息!请重新查找。";
		woFILE.close();
		exit(0);
	}
	Temp = temp->next;
	temp->next = temp->next->next;
	delete Temp;//回收被剔除的节点空间
	Temp = NULL;
	temp = head->next;
	while (temp)         //新的链表放入input文件
	{
		wiFILE << temp->ID << " " << temp->name << " " << temp->age << " " << temp->sex << " " << temp->language << " " << temp->score << endl;
		temp = temp->next;
	}
	woFILE.close();
	wiFILE.close();
	return head;
}

void admin_inf::append(admin_inf::person* head, admin_inf::person* s)
{
	ofstream wiFILE("input.txt", ios::app);//app以补加的形式打开
	ofstream woFILE("out.txt", ios::out);
	while (s != NULL)
	{
		wiFILE << s->ID << " " << s->name << " " << s->age << " " << s->sex << " " << s->language << " " << s->score << endl;
		s = s->next;
	}
	admin_inf::person* temp = head->next;
	while (temp != NULL)
	{
		woFILE<< temp->ID << " " << temp->name << " " << temp->age << " " << temp->sex << " " << temp->language << " " << temp->score << endl;
		temp = temp->next;
	}
	wiFILE.close();
	woFILE.close();
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值