项目:C++在线测评系统

本文介绍了一个基于C++的在线测评系统项目,包括项目思路和具体实现。主要模块有在线编译和题目列表。在线编译使用cpp-httplib搭建服务器,处理用户代码的urldecode,并通过子进程进行编译和运行。题目列表则从数据库中加载并使用ctemplate渲染页面。项目实现了基础的测评功能,未来计划扩展更多特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目思路

之前写过一个基于http的在线编译器,可以完成代码的编译过程,但是在leetcode上刷题的时候忽然想到在线OJ不就是一个功能更强大的在线编译器吗?在基础的编译功能上加上了题目列表页的展示,每个题目都有对应的序号,名称以及描述,于是想着能不能自己对这个项目再进行进一步的扩充

要实现一个简易的在线OJ,有几个大的模块需要去实现,最主要的是在线编译,编译功能可以在服务器上使用子进程进程替换使用g++指令来完成,题目存储在数据库中,当服务器启动就把题目从数据库中加载到内存上,客户端请求哪个题目就将题目的具体信息经过渲染返回给客户端,客户端通过题目描述将具体的代码上传,最终得出结果。

具体实现

在线编译模块
  • 在线测评,势必要使用http服务器来支持在线功能,这里使用cpp-httplib来完成对http服务器的搭建,客户端输入代码会有#&等特殊字符,HTTP使用POST方式进行传输时会对特殊字符进行重新编码,所以在服务器中得到用户代码时必须要先对代码进行urldecode,否则是绝对无法通过编译的。编译的具体文件是需要根据不同时间的每个用户来进行区分的,对于每次编译来说,要完成整个过程,就必不可少的创建六类文件,源码文件,标准输入文件,编译错误文件,生成的可执行文件,标准输出文件,标准错误文件。

解析用户输入


	static void cutString(const std::string& input_str, std::vector<std::string>& output_vec, std::string cut_str) {
   
		boost::split(output_vec, input_str, boost::is_any_of(cut_str), boost::token_compress_off);
}
	static void codeToKv(const std::string& user_body, Json::Value& req) {
   
		// 先对用户输入的body进行&切分
		std::vector<std::string> tmp_vec;
		std::unordered_map<std::string, std::string> code_kv;
		boostUtil::cutString(user_body, tmp_vec, "&");

		// 再进行urldecode解析,对等号进行切分
		for(const auto & k : tmp_vec) {
   
			std::vector<std::string> code_vec;
			boostUtil::cutString(k, code_vec, "=");
			code_kv[code_vec[0]] = urlCodeParse::urlDecode(code_vec[1]);
		}

		//将结果写入json
		for(auto v : code_kv) {
   
			req[v.first] = v.second;
		}
	}
  • urldecode之后将用户输入代码构造成Json字符串,交给编译模块来进行编译运行,编译之前服务器会对不同的输入创建一个唯一的标示,用来区分不同的用户输入,编译使用子进程程序替换,父进程阻塞等待子进程完成编译,编译完成之后使用stat来判断是否生成可执行文件进一步判断编译是否成功,同时将编译过程中的错误信息记录到编译错误文件中

编译过程

static bool compile(std::string fileName) {
   
	char *cmd[20] = {
   0};
	char space[20][50] = {
   {
   0}};
	for(int i = 0; i < 20; i++) {
   
		cmd[i] = space[i];
	}
	sprintf(cmd[0], "%s", "g++");
	sprintf(cmd[1], "%s", srcFilePath(fileName).c_str());
	sprintf(cmd[2], "%s", "-o");
	sprintf(cmd[3], "%s", exeFilePath(fileName).c_str());
	sprintf(cmd[4], "%s", "-std=c++11");
	cmd[5] = NULL;

	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值