项目背景
在某一项目中,遇到了需要自制命令系统的需求,而这个模块的复用性很高,因此单独拉出来做一个子项目
更新日志
[2024.10.15 - 10:00] 增
项目进度
----[ 2024.10.15 10:00 ]----
- 首先实现最基础的输入输出功能,用std::getline读入行再分割成字符串数组
- main.cpp
#include <iostream>
#include <windows.h>
#include <vector>
#include <string>
#include <cstring> //for std::strtok
#include "cmd_sys.h"
//using namespace std; //byte冲突,在后续项目中要用到
//封装成模块时,应删掉所有下面的using,避免冲突
using std::cin;
using std::cout;
using std::endl;
using std::string;
using std::vector;
void mainloop(void) {
string full_cmd;
string cmd;
char* arg_; //个人习惯使用"<变量名>_"作为临时变量名
vector<string> args;
while(1) {
cout << "> ";
std::getline(cin, full_cmd);
cmd = std::strtok(full_cmd.data(), " ");
arg_ = std::strtok(NULL, " ");
while (arg_!=NULL) {
args.push_back(arg_);
arg_ = strtok(NULL, " ");
}
for (int i=0; i<args.size(); ++i) {
cout << args[i] << endl;
} //debug
if (cmd_dict.find(cmd)!=cmd_dict.end()) {
(cmd_dict.at(cmd))(args);
}
}
}
int main(void) {
SetConsoleOutputCP(65001); //中文输出
cout << "命令系统 - Command System" << endl << "By: SoliCoder" << endl << endl;
mainloop();
return 0;
}
坑点1:用C++的std::strtok实现python中的split功能
- std::getline需要full_cmd为std::string类型
但std::strtok要分割的字符串却必须是char*类型
又不能直接强转,查了半天查到可以调用std::string对象的data方法获取char*类型的字符串
Soli评: (string和char*要不你俩打一架吧,为啥string库内部的函数也不能统一成string啊)
----[ 2024.10.24 22:30 ]----
- 然后是命令系统的核心,根据输入的命令调用对应的函数
- cmd_sys.h
#pragma once
#include <vector>
#include <string>
using std::vector;
using std::string;
void cmd_help(vector<string> args);
void cmd_exit(vector<string> args);
void cmd_echo(vector<string> args);
//命令字典,key为命令名,value为对应的函数指针
extern const std::map<string, void (*)(vector<string>)> cmd_dict;
- cmd_sys.cpp
#include "cmd_sys.h"
void cmd_help(vector<string> args) {
cout << "帮助 - help" << endl;
cout << "显示帮助信息" << endl;
}
void cmd_exit(vector<string> args) {
cout << "退出 - exit" << endl;
cout << "退出命令系统" << endl;
exit(0);
}
void cmd_echo(vector<string> args) {
cout << "回显 - echo" << endl;
for (int i=0; i<args.size(); ++i) {
cout << args[i] << endl;
}
}
const std::map<string, void (*)(vector<string>)> cmd_dict = {
{"help", cmd_help},
{"exit", cmd_exit},
{"echo", cmd_echo}
}; //注意这里的初始化方式
坑点2:map的初始化方式
- 这里用了C++11的map,但初始化方式有点奇怪
- 应该用花括号{}包裹,而不是用逗号分隔
- 而且,这里的初始化方式和python的dict初始化方式不太一样
标签:std,args,string,cmd,System,命令,子项目,using,include From: https://www.cnblogs.com/SoliGhost/p/18501461Soli评: 你这个map初始化方式真的很奇怪,我之前也没注意到,不过你这个初始化方式应该是正确的。