2012-10-31 18 views
9

Obecnie pracuję nad aplikacją C++ dla systemu Linux. Będzie on być uruchamiany z linii poleceń, a następnie po uruchomieniu muszę być w stanie wydawać polecenia, aby kontrolować jego wykonanie, najlepiej coś jak następuje:Interfejs wiersza poleceń w C++

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

sobie wyobrazić, że jest to stosunkowo proste zadanie, ale mam nie ma pojęcia, jak taki interfejs zostanie wywołany w celu jego wyszukania. Czy ktoś wie o bibliotece lub przykładzie, który może wykonać tę funkcję? Czy muszę napisać własną przy użyciu cout i cin? Jeśli tak, czy byłoby jakieś preferowane podejście?

+1

C++ nie ma refleksji. Musisz to obejść. – chris

+0

Jeśli nie wiesz, jak to zrobić, nie powinieneś pisać aplikacji uruchamianych przez administratora ... – Barmar

+3

@Barmar Hiperbolicznie jest powiedzieć, że ta aplikacja musi być uruchamiana przez su, i moreso powiedzieć komuś nie powinny pisać aplikacji uruchamianych przez superużytkowników ze względu na postrzegany poziom wiedzy specjalistycznej. –

Odpowiedz

13

Polecam do tego bibliotekę GNU readline. Dba o żmudną pracę z liniami wprowadzania danych i pozwala użytkownikowi edytować linię za pomocą backspace, lewej i prawej strzałki itd., A także przywoływać starsze polecenia za pomocą strzałki w górę, a nawet wyszukiwać starsze polecenia za pomocą^R, itp. Readline jest instalowany z typowymi dystrybucjami podobnymi do systemu Unix, jak na przykład linux, ale jeśli go nie masz, możesz go znaleźć here.

Edit: Tutaj jest minimalny readline przykład:

#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

Możesz napisać swoją aplikację jako aplikacja TCL lub python i używać ich jako front-end.

1

Musisz przynajmniej częściowo rzucić własną. "GNU readline" może nieco pomóc; sprawdź, czy na http://en.wikipedia.org/wiki/GNU_readline masz krótki program, który jest "szkieletem", który osiąga to i wokół którego możesz dodać kod.

1

Powinieneś prawdopodobnie rzucić okiem na the readline library. Ma trochę krzywej uczenia się, ale wciąż jest znacznie łatwiejsze niż samodzielne tworzenie pełnego CLI. Sprawdź licencję, ponieważ może to nie być odpowiednie dla twojego projektu.

5

Biblioteka GNU readline jest wielki, jeśli chcesz pełne możliwości edycji wiersza i historii, ale jeśli proste zachęty jest wystarczająca (lub jeśli nie chcesz licencja GNU), to można to zrobić tylko z biblioteki standardowej:

#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

Zgadzam się z komentarzem Chrisa, że ​​będzie to trudniejsze w języku, który nie jest refleksyjny. W C++ musisz jawnie odwzorować wszystko, co wpiszesz w konkretną funkcję.

Jeśli masz zamiar toczyć własne, Twój ogólny projekt powinien wyglądać mniej więcej tak:

  • Czytaj linię wejściową (najprawdopodobniej przy użyciu cin.getline na sznurku)
  • zidentyfikować pierwsze słowo i określić, czy mapuje ona do dowolnej funkcji (np. można użyć prostej instrukcji przełącznika, tabeli mieszania, itp.)
  • Jeśli nie mapuje funkcji, opublikuj błąd i ponownie wydrukuj monit.
  • Jeśli robi mapę, musisz sprawdzić inne słowa w linii.
  • Dla każdego innego słowa, będziesz musiał przekonwertować ciąg znaków na dowolny typ danych, jaki chcesz, jako parametry funkcji na podstawie słowo po słowie (tu będą przydatne stringy).
  • Teraz musisz upewnić się, że podane parametry są poprawne dla funkcji, którą wywołałeś. Możesz sprawdzić je przed wywołaniem funkcji lub sprawdzić błędy wewnątrz funkcji.
  • Po sprawdzeniu nazwy funkcji i poprawności parametrów (oraz prawidłowego numeru) można wywołać funkcję.

W języku refleksyjnym, pierwsza połowa tego jest znacznie uproszczona, ponieważ możliwe jest przekonwertowanie ciągu znaków bezpośrednio na nazwę funkcji.

+1

Gorąco polecam 'std :: getline' zamiast' std :: istream :: getline'. – chris

2

GNU readline jest zdecydowanie doskonałym wyborem, jak sugerowali inni. Jeśli problemy z licencją zmusiłyby Cię do wykluczenia tego, powinieneś wtedy rozważyć linenoise.

+0

Wygląda na to, że lignina zapewnia również funkcję ukończenia, która może być świetna. – etham

1

zdawać sobie sprawę z licencją GPL z GNU Readline. W odpowiedziach ludzie wspomnieli o licencji GPL na readline GNU. W tej odpowiedzi chciałbym podkreślić konsekwencje licencji GPL - które nowi użytkownicy/programiści mogą przeoczyć.

Tekst skopiowany z https://en.wikipedia.org/wiki/GNU_Readline

wybór GPL jako licencji GNU readline za [edytuj] GNU readline jest wyróżnia będąc bezpłatną bibliotekę oprogramowania, który jest licencjonowany w ramach GNU General Public License (GPL) zamiast GNU Lesser General Public License (LGPL). Biblioteki wolnego oprogramowania często mają licencję w ramach LGPL, na przykład biblioteka GNU C, GNU gettext i FLTK.

deweloperem aplikacji, która zdecyduje się na link do LGPL licencjonowane biblioteki przy tworzeniu nowej aplikacji wymagane jest posiadanie licencjonowanej biblioteki LGPL których używa pozostają pod LGPL przy dystrybucji połączone wynikające aplikacji. Część połączonej aplikacji z wyłączeniem biblioteki objętej licencją LGPL może pozostać pod oryginalną licencją . [1] Jest to sprzeczne z tym, że programista wybrał opcję , korzystając z biblioteki licencjonowanej GPL, aby utworzyć nową aplikację. W takim przypadku cała połączona wynikowa aplikacja musi mieć licencję w ramach GPL, jeśli jest rozpowszechniana, zgodnie z sekcją 5 instrukcji . GPL. [2] [3]

Implikacje licencji GPL GNU readline za [edytuj] Ważnym przykładem wniosku zmieniającego jego licencji do przestrzegania copyleft warunki GNU readline jest clisp, implementacja Common Lisp. Pierwotnie wydany w 1987 r., Zmienił się na licencję GPL w 1992 r., [4] po wymianie e-mailowej między jednym z oryginalnych autorów CLISP, Bruno Haible, a Richardem Stallmanem, w którym Stallman przekonywał [5], że linkowanie readline w CLISP oznaczało, że Haible był zobowiązany do ponownego licencjonowania CLISP na licencji GPL, jeśli chciał rozpowszechniać implementację CLISP, która używała readline. [6]

alternatywnej biblioteki edycji wiersza poleceń, które są permissively licencją mogą być wykorzystywane przez projekty oprogramowania, które chcą wprowadzić do edycji wiersza poleceń funkcjonalność, ale chcą pozostać pod licencji pozwalającej. Typową z nich jest licencjonowana licencja BSD. Niektóre aplikacje, takie jak MariaDB [7] lub PHP [8], pozwalają użytkownikowi na wybrać w czasie kompilacji, czy połączyć z GNU Readline lub z libedit. Inne biblioteki do edycji wiersza poleceń mają podwójny cel: mają interfejsy API, które wyrównują niektóre z głównych projektów i mają zgodne warunki licencji zgodne z . Przykładem jest biblioteka Haskeline, , która udostępnia interfejs API zgodny z Haskell zarówno dla kompilatora Glasgow Haskell [9], jak i dla innych projektów Haskell, które wymagają edycji linii usług . [10]

Łącza do kilku takich bibliotek są wymienione w linkach zewnętrznych.