想要创建一个应用程序,它打开控制台,并从用户作为命令输入

Want to create application which open console and take input from user as a command

本文关键字:控制台 用户 输入 命令 创建 应用程序 一个      更新时间:2023-10-16

我想创建控制台应用程序,从用户接收命令作为输入。像

●在运行的应用程序上,它应该显示一个提示

●在提示符下,用户可以输入以下命令

〇exit: to exit

〇parse:解析给定文件

〇show last:显示上次解析文件的信息

〇show:显示所有已解析文件的信息

〇del: delete info .

解析和其他逻辑我知道。我只是想如何在应用程序中创建控制台,它将字符串作为用户的命令。

使用std::cin和'std::string',仅将用户输入与exit, parse等进行比较。

注意:这主要是基于我对OP最初问题的解释。到目前为止,它还没有完全回答这个问题,但是我将把它作为一个答案,如果其他人能够从中受益的话。

你可以从创建一个叫做CommandBase的类开始。为了演示的目的,我将使用字符串和向量。

class CommandBase{
protected:
    std::string m_name;//The internal name
    std::string m_help;//The internal help line
public:
    //The public interface for name.
    const std::string &name = m_name;
    //The public interface for the help line.
    const std::string &help = m_help;
    virtual void execute(const std::string &line){}
    CommandBase(){
        m_name = "BASE_COMMAND";
        m_help = "BASE_HELP_MESSAGE";
    }
};

在本例中,我们将实现一个退出程序的函数和一个将输入的数字翻倍的函数。

class CommandExit : public CommandBase{
public:
    CommandExit(){
        m_name = "exit";
        m_help = "exit ~ Will cause the program to terminate. ";
    }
    virtual void execute(const std::string &line){
        std::cout<<"Exiting"<<std::endl;
        exit(0);
    }
}commandExit;
class CommandDouble : public CommandBase{
public:
    CommandDouble(){
        m_name = "double";
        m_help = "double <number1> ~ Will output number1 times two. ";
    }
    virtual void execute(const std::string &line){
        int i = std::atoi(line.c_str());
        std::cout<<"The double of: "<<i<<" is "<<i*2<<std::endl;
    }
}commandDouble;

现在我们已经完成了commanddexit,我们需要调用函数。让我们创建一个函数foo,它将从std::cin中读取命令和参数。

void foo(){
    std::vector<CommandBase*> commandList;
    commandList.push_back(&commandExit);
    commandList.push_back(&commandDouble);
    commandList.push_back(&commandPower);
    commandList.push_back(&commandFileWrite);

    std::string ourCommand;
    std::string ourParameters;
    help(commandList);
    while(true){
        std::cin>>ourCommand;
        std::getline(std::cin,ourParameters);
        //Remove any preceeding whitespace.
        ourParameters.erase(ourParameters.begin(), std::find_if(ourParameters.begin(), ourParameters.end(), std::bind1st(std::not_equal_to<char>(), ' ')));
        std::cout<<"We will execute the command: "<<ourCommand<<std::endl;
        std::cout<<"We will use the parameters: "<<ourParameters<<std::endl;

        bool foundCommand = false;
        for(unsigned i = 0; i < commandList.size(); ++i){
            if(commandList[i]->name == ourCommand){
                foundCommand = true;
                commandList[i]->execute(ourParameters);
                break;
            }else continue;
        }
        if(!foundCommand){
            std::cout<<"The command: "<<ourCommand<<" was not reconized. Please try again."<<std::endl;
            help(commandList);
        }
    }
}

现在为了测试,我们将首先提供一个无效命令的参数:

invalidCommand1 invalidParam1

我们收到输出:

我们将执行命令invalidCommand1

我们将使用参数invalidParam1

无法识别命令:invalidCommand1。请重试。

现在让我们测试程序是否会正确地翻倍。我们将提供输入:

双5

,我们收到输出:

我们将执行命令:double

我们将使用参数:5

: 5的double = 10

最后我们用输入检查退出情况:

退出

我们收到输出:

我们将执行命令:exit

我们将使用以下参数:

退出

程序成功终止。

正如我们所看到的,所有的选项都在正确执行,您可以很容易地定义新命令并处理您选择的提供的参数。我希望这对你有帮助。

假设你想创建需要多个参数的更高级的命令。首先,我们需要创建一个函数来拆分"line"中的参数。

int split(const std::string& line, const std::string& seperator, std::vector<std::string> * values){
    std::string tString = "";
    unsigned counter = 0;
    for(unsigned l = 0; l < line.size(); ++l){
        for(unsigned i = 0; i < seperator.size(); ++i){
            if(line[l+i]==seperator[i]){
                if(i==seperator.size()-1){
                    values->push_back(tString);
                    tString = "";
                    ++counter;
                }else continue;
            }else{
                tString.push_back(line[l]);
                break;
            }
        }
    }
    if(tString!="")values->push_back(tString);
    return counter;
}

现在我们可以有效地拆分代码,让我们实现两个新函数。一个是给定数字的给定次幂,另一个是将消息写入文件。

class CommandPower : public CommandBase{
public:
    CommandPower(){
        m_name = "pow";
        m_help = "pow <number1> <number2> ~ Will raise number 1 to the power of number 2. ";
    }
    virtual void execute(const std::string &line){
        double d, exp;
        std::cout<<"Param:"<<line<<std::endl;
        std::vector<std::string> vals;
        split(line," ",&vals);
        assert(vals.size()>=2);//We don't want a nasty Out Of Bounds.
        for(unsigned i = 0; i < vals.size(); ++i){
            std::cout<<"Vals["<<i<<"] = "<<vals[i]<<std::endl;
        }
        d = std::atof(vals[0].c_str());
        exp = std::atof(vals[1].c_str());
        std::cout<<d<<" raised to the power of: "<<exp<<" is "<<pow(d,exp)<<std::endl;
    }
}commandPower;
class CommandFileWrite : public CommandBase{
public:
    CommandFileWrite(){
        m_name = "write";
        m_help = "write <filename> [message] ~ Will append the message to the specified file. ";
    }
    virtual void execute(const std::string &line){
        std::cout<<"Param:"<<line<<std::endl;
        std::vector<std::string> vals;
        split(line," ",&vals);
        assert(vals.size()>=1);//We don't want a nasty Out Of Bounds.
        for(unsigned i = 0; i < vals.size(); ++i){
            std::cout<<"Vals["<<i<<"] = "<<vals[i]<<std::endl;
        }
        //The stream for the file we will save.
        std::ofstream fts;
        fts.open(vals[0].c_str(), std::ios::out|std::ios::app);
        if(fts.is_open()){
            for(unsigned i = 1; i < vals.size(); ++i){
                if(i+1<vals.size()) fts<<vals[i]<<" ";
                else fts<<vals[i]<<std::endl;
            }
        }else{
            std::cerr<<"Cannot open the file: "<<vals[0]<<std::endl;
            return;
        }
    }
}commandFileWrite;

这两个函数都可以通过查看

来测试:输入:

输出:

10的2次方等于100

对于fileWrite我们可以检查:

write out.txt消息。

当我们查看生成的out.txt文件时,它包含:

这是一条消息。

再一次,我希望这对你有帮助。编辑:

我没有任何关于输入是否正确的错误检查,所以如果需要的话,您可能需要添加它。(例如CommandDouble不检查参数是否实际上是数字)无论如何,如果你有任何问题;尽管问吧。

编辑2:

我刚刚看到你在我开始研究这个问题之后更新了你的问题。您必须为文件解析实现CommandBase的子元素(取决于您希望如何解析它)。您应该能够使用此框架或类似的框架来创建Parse Command。至于创建帮助,你可以这样做:

void help(){
std::cout<<"---------------Operating Instructions---------------"<<std::endl
         <<"Use double <number> to double an inputted number    "<<std::endl
         <<"Use exit to close the program                       "<<std::endl;
}

可以在用户输入错误命令和程序开始时调用它。

编辑3:

更新了一些代码,并添加了一些函数来演示如何解析参数。此外,我还调整了帮助功能以读取每个命令的帮助文本,并将其调用合并到foo中。完整的源代码可以在http://pastebin.com/y0KpAu5q

找到。编辑4:

对于那些可能有帮助的,代码中使用的包含是:

#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <fstream>