多线程之简易注册验证程序

问题描述

使用VC2010或以上版本编写一个多线程注册验证程序,要求:

  • 通过对话框输入若干人的学号和姓名,并存入列表中作为注册记录。
  • 用户输入一个学号,程序能通过多线程的方式与注册记录比对来验证其是否已注册,并弹出提示框。

解决方案

以下程序基于VS2019设计,VS2010可能无法运行。

  • 制作GUI界面

首先新建一个MFC应用
图片1

应用程序类型选择基于对话框,点击完成
图片2

在资源视图打开以下界面,开始制作GUI界面
图片3

从工具箱中添加控件,本项目主要用到三个控件,按钮Button、可编辑文本框Edit Control、静态文本框Static Text
图片4

制作好的GUI如下(界面有点简陋,求轻喷):
图片5

  • 添加代码

完成GUI制作后,我们就可以往StudengsManageSystemDlg.cpp中添加代码了。根据题目的要求,我们需要保存学生的学号和姓名,因此我们创建一个包含学号、姓名以及一个构造函数的学生类,为了方便之后的查询对比,将学号用long long型数据保存。

// 创建一个学生类
class Student
{
public:
	long long SID;
	CString Name;
	Student(long long sid, CString name)
	{
		SID = sid;
		Name = name;
	}
};

接下来我们需要一个列表来保存每个学生类的实例

// 新建一个学生列表
vector<Student> stulist;

然后在GUI设计界面双击保存按钮,跳转到这个保存按钮的回调函数

void CStudentsManageSystemDlg::OnBnClickedButton1()
{
	CString sid;
	CString name;
	// 将文本框1的内容输出到sid
	GetDlgItem(IDC_EDIT3)->GetWindowText(sid);
	// 将文本框2的内容输出到name
	GetDlgItem(IDC_EDIT4)->GetWindowText(name);
    // 判断待保存的学号和姓名中是否有空值
	if (name == "" || sid == "")
	{
		CString str_prompt = CString("提示框");
		CString str = CString("学号/姓名不能为空!");
		MessageBox(str, str_prompt, MB_OK);
		return;
	}
    // 学号必须为数字,如果存在非数字则返回,并弹出提示框
	for (int i = 0; i < sid.GetLength(); i++)
	{
		if (sid[i] < '0' || sid[i] > '9')
		{
			CString str_prompt = CString("提示框");
			CString str = CString("请输入正确的学号!");
			MessageBox(str, str_prompt, MB_OK);
			return;
		}
	}
	// 将上述内容存到学生列表中
	stulist.push_back(Student(_ttoll(sid), name));
}

由于题目要求使用多线程的方式来验证是否注册,所以需要编写一个查询函数search_task(long long sid),它的形参是待查询的学号。

void search_task(long long sid)
{
	if (stulist.size() == 0)
	{
		CString str_prompt = CString("提示框");
		CString str = CString("学生列表为空!");
		MessageBox(NULL, str, str_prompt, MB_OK);
		return;
	}
	for (int i = 0; i < stulist.size(); i++)
	{
		if (stulist[i].SID == sid)
		{
			CString str_prompt = CString("提示框");
			MessageBox(NULL, CString("姓名为:") + stulist[i].Name, str_prompt, MB_OK);
			break;
		}
		else
		{
			if (i == stulist.size() - 1)
			{
				CString str_prompt = CString("提示框");
				CString str = CString("未注册!");
				MessageBox(NULL, str, str_prompt, MB_OK);
			}
		}
	}
}

最后向查询按钮中添加回调函数

void CStudentsManageSystemDlg::OnBnClickedButton2()
{
	CString sid;
	GetDlgItem(IDC_EDIT5)->GetWindowText(sid);
    // 待查询的学号不能为空
	if (sid == "")
	{
		CString str_prompt = CString("提示框");
		CString str = CString("查询学号不能为空!");
		MessageBox(str, str_prompt, MB_OK);
		return;
	}
	for (int i = 0; i < sid.GetLength(); i++)
	{
		if (sid[i] < '0' || sid[i] > '9')
		{
			CString str_prompt = CString("提示框");
			CString str = CString("请输入正确的学号!");
			MessageBox(str, str_prompt, MB_OK);
			return;
		}
	}
	long long SID = _ttoll(sid);
	// 开启查询线程
	thread t(search_task, SID);
	// 必须将线程join或者detach,子线程结束后主进程才可以退出
	t.detach();
}
运行程序

完成上述操作后,就可以测试程序了。

  • 保存2017000000001 王小明 2017000000002 王大明,并查询2017000000001以及2017000000003,得到以下结果。
测试结果1 测试结果2
  • 保存2017xxxxxxxx1,弹出提示框,结果正确。
测试结果3
结论

测试程序时,可能没有体现出多线程的作用,因为输入的样本数较少,执行查询任务时也就一瞬间的事。但是样本数量比较大时,查询任务将会耗费比较多的时间,如果将查询任务放在回调函数中执行,将会导致在查询过程中,系统无法响应,表现为系统卡住。

当然当样本数较大时,还可能发生前一次查询还没结束,另一次查询就发起了的情况,这时候两次查询都需要用到学生列表,所以

由于时间限制,并没有将学生列表中的数据保存到一个本地文件中,所以本程序中所有输入的数据都保存在一个动态列表中,当程序关闭时,这些数据将会丢失。

完整项目在这里(其实按照上述步骤操作应该能得到一个差不多的程序):

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值