首页 > 编程语言 >【子项目:命令系统(Command System)】C++自制命令系统( 开发ing | 踩坑记录 )

【子项目:命令系统(Command System)】C++自制命令系统( 开发ing | 踩坑记录 )

时间:2024-10-24 22:20:52浏览次数:8  
标签:std args string cmd System 命令 子项目 using include

项目背景

在某一项目中,遇到了需要自制命令系统的需求,而这个模块的复用性很高,因此单独拉出来做一个子项目

更新日志

[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初始化方式不太一样

Soli评: 你这个map初始化方式真的很奇怪,我之前也没注意到,不过你这个初始化方式应该是正确的。

标签:std,args,string,cmd,System,命令,子项目,using,include
From: https://www.cnblogs.com/SoliGhost/p/18501461

相关文章

  • 【Linux】cp -r 命令实验
    1.命令说明 命令:cp-r source dest说明:该命令复制source 到 dest。可以单个文件复制,也可以带目录层级复制。     source是具体文件时,dest如果是目录,即带/的,则文件生成在dest目录中。如果dest是不带/的,文件换名为dest文件,内容复制过去。    ......
  • 要使用 netsh 命令更新以太网连接的 IPv6 DNS 服务器地址,可以通过以下步骤进行操作。
    要使用netsh命令更新以太网连接的IPv6DNS服务器地址,可以通过以下步骤进行操作。以下是设置IPv6DNS的命令示例。使用 netsh 设置以太网的IPv6DNS打开命令提示符:以管理员身份运行命令提示符。输入以下命令:bashCopyCodenetshinterfaceipv6setdnsname......
  • linux目录和文件命令
    目录命令ls功能:显示目录的列表用法ls[参数][对象]-a:显示所有文件,包括隐藏文件-l:显示文件详细信息-t:按照时间顺序排序-r:逆向排序pwd功能:显示当前目录的绝对路径用法:pwdcd功能:切换操作目录用法:cd[对象].当前目录..上一层目录上一次所在目录~home目......
  • Linux常用命令
    1、cd-切换当前目录这是一个最基本,也是最常用的命令,它用于切换当前目录,它的参数是要切换到的目录的路径,可以是绝对路径,也可以是相对路径。cd/root #切换到目录/rootcd./path #切换到当前目录下的path目录中,“.”表示当前目录cd../path #切换到上层目录中的path目录中,“..”......
  • java启动命令详解
    java-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8002-server-Xms4g-Xmx6g-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=/data/data/dump.bin-Dfile.encoding=UTF-8-Djava.awt.headless=true-XX:+UseG1GC-XX:MaxGCPauseMillis=200-XX:G1H......
  • Docker常用命令记录(随时更新)
    Docker常用命令镜像操作保存镜像为tar包dockersave-o<文件名>.tar<镜像名>:<版本号>例如:dockersave-omyimage.tarmyimage:latest从tar包加载镜像dockerload-i<文件名>.tar例如:dockerload-imyimage.tar查看本地所有镜像dockerimages可以加......
  • Linux 中 awk命令整列的替换
     001、测试数据[root@localhosttest2]#lsa.txt[root@localhosttest2]#cata.txt0102030405060708091011121314151617181920212223242526......
  • docker学习-常用命令
    获取镜像dockerpullubuntu启动容器dockerrun-itubuntu/bin/bash停止一个容器dockerstop<容器ID>停止的容器可以通过dockerrestart重启:dockerrestart<容器ID>进入容器dockerattachdockerexec:推荐大家使用dockerexec命令,因为此命令会退出容器终......
  • OpenEuler 系统中 fdisk 工具使命令详解
    OpenEuler系统中fdisk工具使命令详解简介在OpenEuler操作系统中,fdisk是一个强大的磁盘分区工具,它支持创建、删除和修改磁盘分区等操作。本指南将详细说明如何使用fdisk工具,以帮助用户更高效地管理磁盘分区。安装与启动在OpenEuler系统中,fdisk工具通常预装在......
  • centos(linux): systemctl列出所有运行中/自启动的服务
    一,列出所有服务:systemctllist-units--type=service二,列出所有运行中的服务1,用--state指定状态systemctllist-units--type=service--state=running2,直接grepsystemctllist-units--type=service|greprunning三,列出所有自启动的服务1,列出所有自启动的单元......