在C++中创建交互式提示
Creating an Interactive Prompt in C++
我有一个程序,它应该从控制台读取命令,并根据命令执行几个操作之一。这是我到目前为止所拥有的:
void ConwayView::listening_commands() {
string command;
do {
cin >> command;
if ("tick" == command)
{
// to do
}
else if ("start" == command)
{
// to do for start
}
...
} while (EXIT != command);
}
如果有大量命令,则使用switch
代替if
语句会有所帮助。您建议使用哪些模式来提供交互式命令行?
有多种方法可以解决这个问题,什么是"正确"的解决方案是有争议的。如果我为自己的工作解决它,我会创建一个自定义结构的表。像这样:
struct CommandStruct {
char *command;
int (*commandHandler)(/*params*/);
} commandTable[] = {
{ "tick", tickCommand },
{ "start", startCommand },
...
};
然后,我的处理循环将遍历此表的每个元素,寻找正确的匹配项,例如:
for (int i = 0; i < TABLE_SIZE; ++i) {
if (command == commandTable[i].command) { /* using whatever proper comparison is, of course */
commandTable[i].commandHandler(/*params*/);
break;
}
}
不是真正的模式,但通常是一个很好的方法:
#include <map>
#include <functional>
#include <string>
#include <iostream>
typedef std::map< std::string, std::function<void(void)> > command_dict;
// ^^^^^^^^
// the signature of your commands. probably should have an error code.
void command1() { std::cout << "commanda" << std::endl; }
void command2() { std::cout << "commandb" << std::endl; }
void command3() { std::cout << "commandc" << std::endl; }
int main() {
command_dict c;
c["a"] = &command1;
c["b"] = &command2;
c["c"] = &command3;
std::string input;
while(std::getline(std::cin, input)) { // quit the program with ctrl-d
auto it = c.find(input);
if(it != end(c)) {
(it->second)(); // execute the command
} else {
std::cout << "command "" << input << "" not known" << std::endl;
}
}
}
如果命令数量很少,可能的参数真的很少,你可以继续切换大小写!
如果命令数量增加,请考虑命令设计模式(恕我直言,这是某种伪装的策略模式:cf 使用策略模式和命令模式来区分命令和策略模式)。
如果大多数命令都共享同一行为的一部分,请不要忘记模板方法模式。
如果创建命令对象的复杂性增加(即解码/理解命令行输入的复杂性),您应该开始查看解释器设计模式
如果在解释器模式的帮助下进行设计时,您碰巧看到了一些复杂性(如果解释器需要太多工作,您会看到语法问题等等),那么您可能应该查看DSL,领域特定语言,并设计适合(并且仅适合)您自己的输入的语言。
if
-else
梯子很好。
原则上它可以替换为map<string, Function>
,但这对这种具体情况没有任何好处(即使有大量命令,它也没有特别的收益而增加了复杂性)。
当我最初写这篇文章时,我忘了提到:
- 使命令处理程序具有单独的函数。
如果你不这样做,那么if
-else
梯子可能会变得非常混乱......map
解决方案需要单独的功能,因此看起来比直接在这里if
-else
梯子更干净一些。但实际上,单独的功能提供了一定程度的清晰度,而map
则略有减损(在维护地图方面增加了额外的工作,以及额外的间接级别来应对)。
另一方面,由于"从控制台读取命令"表示交互式输入,因此图片中有用户,您不希望从同一行输入中读取两个或多个命令。因为这会搞砸提示,并且对用户来说似乎很困惑。因此,与其使用>>
一次读取输入的"单词",不如使用std::getline
一次读取一整行输入。
使用新的和改进的方式随意执行一堆命令:
int happy_time = 5;
int a = happy_time;
int muddy_dirt = 1;
int b = muddy_dirt;
int c = happy_time * muddy_dirt //really messy stuff
这可能是最不复杂的方法...
如果您的命令很大,则必须使用类似数据库的访问。
- 有没有办法提示用户使用哪种数据类型作为模板 c++
- 与 stdio 同步是否使程序 I/O 非交互式?
- 外壳包装器句柄/执行交互式命令管道C++ UNIX
- 如何使用递归循环我的代码(当用户输入无效输入时,它会再次提示他们)?
- 提示存档文件中的动态库依赖项
- 如何确保用户在一行上提示输入一次时输入名字和姓氏?
- 在 Golang 中等C++结构中提供代码提示/标记
- 为什么 std::cin 不提示用户输入?
- 如何使用打印到 PDF 打印机在 MFC 和 CView 中以编程方式打印而不提示输入文件名?
- 如何在动态创建的CMFCToolbar的工具提示中添加描述?
- 寻找解决这个动态编程问题的提示
- 添加带有 QSyntaxHighlight 和 QTextCharFormat 的工具提示
- 编写一个程序,提示用户输入一个整数,然后输出数字的单个数字和数字的总和
- 编译以下重载<<需要什么enable_if或其他提示?
- 如何在gedit中使用外部工具运行交互式C++程序
- 防止Xcode 9.4无限期索引的提示
- 地图插入(const_iterator提示,值)用法
- 如何重现 Boost 进程文档提示的死锁?
- 为什么我的代码在 c++ 中无限循环.我的代码需要反复提示用户
- 在C++中创建交互式提示