2012-10-31 220 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]

鏈接到幾個這樣的庫被列在外部鏈接。