草庐IT

c++ - 在命令行中创建菜单

coder 2024-02-08 原文

如何在命令行程序中创建菜单?我尝试过类似的东西:

cin >> input;
switch (input) {
  case (1):
    // do stuff
  case (2):
    // ...
}

但后来我遇到了子菜单的问题,并返回到相同的菜单等。我编写的第一个程序(除了练习之外)尝试使用 switch 想法因为菜单有 goto 语句,因为替代方案是一堆(当时)复杂的循环。

最佳答案

如果我试图计算一个人可能创建 1、2、3 菜单的方式,那么在我迭代其中的 1/2 之前我们都已经死了。但这里有一种您可以尝试让您入门的方法(未经测试,您可能需要清理一些东西):

struct menu_item
{
  virtual ~menu_item() {}
  virtual std::string item_text() const = 0;
  virtual void go() = 0;
};

struct print_hello_item
{
  std::string item_text() const { return "display greeting"; }
  void go() { std::cout << "Hello there, Mr. User."; }
};

struct kill_everyone_item
{
  std::string item_text() const { return "Go on murderous rampage"; }
  void go() { for(;;) kill_the_world(); }
};

struct menu_menu_item
{
  menu_menu_item(std::string const& text) : text_(text), items() {}
  void add_item(std::unique_ptr<menu_item> item) { items.push_back(std::move(item)); }
  void go()
  {
    std::cout << "Choose: \n";
    std::for_each(items.begin(), items.end(), [](std::unique_ptr<menu_item> const& item)
    {
      std::cout << "\t" << item->item_text() << "\n";
    });
    std::cout << "\n\n\tYour choice: ";
    int choice = get_number_from_console();
    if (items.size() > choice) items[choice]->go();
  }
  std::string item_text() const { return text_; }

private:
  std::string text_;
  std::vector<std::unique_ptr<menu_item> > items;
};

int main()
{
  menu_menu_item top_item;
  top_item.add(std::unique_ptr<menu_item>(new print_hello_item));
  top_item.add(std::unique_ptr<menu_item>(new kill_everyone_item));

  top_item.go();
}

作为练习,我该如何定义菜单项:

top_level.add()
  ( "Drive off a cliff", &die_function )
  ( "Destroy the world", &global_thermal_nuclear_war )
  ( "Deeper", submenu()
                ( "Hey, check this shit out!", &gawk ))
;

可以以上述框架为起点来完成。

这就是 OO 设计与所谓的“过程”设计之间的区别。我在菜单选择(可以是另一个菜单)的含义背后创建了一个抽象,可以向各个方向扩展。我创建我需要的扩展,将它们放在一起,然后告诉它去。好的 OO 设计就是这样……程序的主要部分是将东西放在一起并告诉它运行。

从中得到的关键不是一定要按照我刚才的方式去做,而是要以不同的方式思考。如果您能理解上述代码的要点,那么您会发现您可以将新项目和新菜单添加到任意深度,而无需处理开关样式导致的那种过于复杂的代码。

关于c++ - 在命令行中创建菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4688055/

有关c++ - 在命令行中创建菜单的更多相关文章

  1. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  4. ruby - 如何在 Ruby 中创建无类 DSL? - 2

    我正在尝试找出如何为我的Ruby项目创建一种“无类DSL”,类似于在Cucumber步骤定义文件中定义步骤定义或在Sinatra应用程序中定义路由。例如,我想要一个文件,其中调用了我的所有DSL函数:#sample.rbwhen_string_matches/hello(.+)/do|name|call_another_method(name)end我认为用我的项目特有的一堆方法污染全局(内核)命名空间是一种不好的做法。因此方法when_string_matches和call_another_method将在我的库中定义,并且sample.rb文件将以某种方式在我的DSL方法的上下文中

  5. ruby-on-rails - 如何在 Rails 3 中创建自定义脚手架生成器? - 2

    有这些railscast。http://railscasts.com/episodes/218-making-generators-in-rails-3有了这个,你就会知道如何创建样式表和脚手架生成器。http://railscasts.com/episodes/216-generators-in-rails-3通过这个,您可以了解如何添加一些文件来修改脚手架View。我想把两者结合起来。我想创建一个生成器,它也可以创建脚手架View。有点像RyanBates漂亮的生成器或web_app_themegem(https://github.com/pilu/web-app-theme)。我

  6. ruby - 为什么在 ruby​​ 中创建 Rational 不需要新方法 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Rubysyntaxquestion:Rational(a,b)andRational.new!(a,b)我正在阅读ruby镐书,我对创建有理数的语法感到困惑。Rational(3,4)*Rational(1,2)产生=>3/8为什么Rational不需要new方法(我还注意到例如我可以在没有new方法的情况下创建字符串)?

  7. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  8. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  9. ruby - 在 Ruby 中创建按公共(public)键值分组的新哈希 - 2

    假设我有一个在Ruby中看起来像这样的哈希:{:ie0=>"Hi",:ex0=>"Hey",:eg0=>"Howdy",:ie1=>"Hello",:ex1=>"Greetings",:eg1=>"Goodday"}有什么好的方法可以将它变成如下内容:{"0"=>{"ie"=>"Hi","ex"=>"Hey","eg"=>"Howdy"},"1"=>{"ie"=>"Hello","ex"=>"Greetings","eg"=>"Goodday"}} 最佳答案 您要求一个好的方法来做到这一点,所以答案是:一种您或同事可以在六个月后理解

  10. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

随机推荐