2012-10-31 179 views
9

我目前正在设计一个Linux C++应用程序。这将在命令行中运行,那么一旦运行我需要能够发出命令来控制它的执行,非常类似如下:C++命令行界面

$ sudo ./myapplication 
APP > 
APP > 
APP > //just pressing return 
APP > openlog test1.txt //APP will now call the openlog function 
APP > 

我想这是一个相对简单的任务,但我有不知道这样一个界面将被称为搜索一个。有人知道可以执行此功能的库或示例吗?还是我需要使用cout和cin编写我自己的?如果是这样,是否会有任何首选方法?

+1

C++没有反射。你必须解决这个问题。 – chris

+0

如果你不知道如何做到这一点,你不应该编写应用程序由超级用户运行.... – Barmar

+3

@Barmar说这个应用程序需要由su运行,并且说某人不应该编写由超级用户运行的应用程序,因为他们具有专业知识水平。 –

回答

13

我为此推荐GNU readline库。它负责获取输入行的繁琐工作,并允许用户使用退格键,左右箭头等编辑他的行,并使用向上箭头调用较旧的命令,甚至使用^ R搜索较旧的命令,等等。Readline安装了典型的类似linux的unix发行版,但如果你没有它,你可以找到它here

编辑:这是一个最小的readline例如:

#include <stdio.h> 
#include <readline/readline.h> 
#include <readline/history.h> 

int main(int argc, char ** argv) 
{ 
    while(1) 
    { 
     char * line = readline("> "); 
     if(!line) break; 
     if(*line) add_history(line); 
     /* Do something with the line here */ 
     free(line); 
    } 
} 
-4

您可以将应用程序编写为TCL或Python应用程序,并将它们用作前端。

1

您将不得不至少部分推出自己的。 GNU readline可能会略有帮助;检查出http://en.wikipedia.org/wiki/GNU_readline是一个简短的程序,它是实现这个功能的“骨架”,并且可以实际添加代码。

1

你应该看看the readline library。它有一点点的学习曲线,但它比你自己重新创建一个完整的CLI还要容易得多。请检查授权,因为它可能不适合您的项目。

5

GNU readline库是巨大的,如果你想全行编辑和历史记录功能,但如果一个简单的提示就足够了(或者,如果你不想在GNU许可证),那么你可以只用标准库做到这一点:

#include <iostream> 
#include <string> 

void process(std::string const & line); 

int main() 
{ 
    for (std::string line; std::cout << "APP > " && std::getline(std::cin, line);) 
    { 
     if (!line.empty()) { process(line); } 
    } 

    std::cout << "Goodbye.\n"; 
} 
2

我与克里斯的评论认为,这将在不反光语言更难。在C++中,你需要明确地将你输入的内容映射到一个特定的函数。

如果你打算推出自己的,你的一般设计应该是这个样子:

  • 读取输入线(最有可能使用cin.getline成字符串)
  • 确定的第一个字并确定它是否映射到任何函数(例如,您可以使用简单的开关语句,散列表等)
  • 如果它不映射到函数,则发布错误并重新打印提示。
  • 如果它确实映射,则必须检查该行中的其他单词。
  • 对于每一个单词,您都必须将字符串转换为您想要的任何数据类型作为函数参数逐字(stringstreams将在这里派上用场)。
  • 现在您必须确保您提供的参数对您调用的函数是合法的。您可以在调用函数之前预先检查它们,或者检查函数内部的错误。
  • 一旦您验证了您的函数名称并且参数是正确的(以及正确的编号),您可以调用该函数。

在反射式语言中,前半部分非常简化,因为您可以将字符串直接转换为函数名称。

+1

我强烈推荐'std :: getline' over'std :: istream :: getline'。 – chris

2

正如其他人所建议的那样,GNU readline是迄今为止最好的选择。如果许可问题会迫使你排除,那么你应该考虑linenoise

+0

似乎linenoise还提供了完成功能,这可能很棒。 – etham

1

注意GPL许可证的的GNU Readline。 在答案中,人们提到了GNU readline的GPL许可证。在这个答案中,我想强调GPL许可的含义 - 哪些新用户/开发人员可能会忽视。

文本从GPL为GNU的ReadLine执照https://en.wikipedia.org/wiki/GNU_Readline

选择复制[编辑] GNU的Readline是 值得注意的是这是 GNU通用公共许可证(GPL)下发布一个免费的软件库,而不是GNU Lesser General Public License(LGPL)。自由软件库在LGPL下经常被授权 ,例如,GNU C库,GNU gettext和FLTK。

谁选择链接到LGPL的应用的开发者建立一个新的应用程序需要有它使用保持在LGPL下分发 合并生成的应用程序时,LGPL许可 库时特许 库。 [1]除了LGPL许可的库之外,合并的 应用程序的部分可以保留在 原始许可证下。这与开发者选择 使用GPL许可库创建新应用程序相反,在这种情况下, 整个组合生成的应用程序在分发时需要在GPL下获得许可 ,以符合 的第5部分GPL。[2] [3]

影响GNU的ReadLine的GPL许可[编辑]一个重要的例子应用改变其许可符合copyleft的GNU的Readline的 条件CLISP,Common Lisp中的实现的 的。 最初于1987年发布,1992年更改为GPL许可,[4] 在CLISP的原始作者Bruno Haible和Richard Stallman之间进行电子邮件交换后,Stallman认为[5] 链接CLISP中的readline意味着如果Haible希望分发使用readline的CLISP的 实现,则需要根据GPL重新许可CLLP。这是permissively 许可

替代命令行编辑库,可通过希望实现 命令行编辑功能的软件项目中使用,但希望保留下 许可认证。其中典型的是BSD授权的libedit。 某些应用程序(如MariaDB [7]或PHP [8])允许用户在编译时选择是否与GNU Readline链接或与libedit链接。其他命令行编辑库具有双重用途: 它们具有API,它们与某些主要项目的API保持一致,并且具有兼容许可条款的 。一个例子是Haskeline库, 公开了一个Haskell兼容API到格拉斯哥Haskell编译器[9]和其他Haskell项目需要行编辑 服务。[10]

链接到几个这样的库被列在外部链接。