2013-08-03 2 views
1

파일 정보에 대한 디렉터리를 검색하는 프로그램을 작성하고 있습니다. 특정 파일 그룹을 스캔하거나 특정 방식으로 스캔하거나 특정 방식으로 출력하기 위해 사용자가 입력 할 수있는 선택적 스위치가 있습니다.여러 명령 줄 스위치 구문 분석

예를 들어

사용자가 입력하는 경우 : filesum -rRc,이 오름차순으로 출력 파일, 재귀 적 검사를하고 만 관련 파일 확장자 (통화 당 | .H | .HPP ) ++ C를 검색합니다.

가능한 한 가장 깨끗한 방법으로 어떻게합니까? 나는 getopt를 살펴 봤지만 구현은 전혀 이해하지 못했고 문서화로 좋은 예제를 찾는 것이 어렵다.

스위치가 입력 된 명령 줄 인수를 문자열로 변환하고 구문 분석을 시도했지만 여러 if 문을 사용하면 인수가 하나만 전환되는지 또는 없는지 확인할 수 있습니다. 다음과 같은 것을 수행 할 수 있습니까? -rc? 또는 어떤 스위치를 입력했는지에 따라 다른 플래그로 while 루프를 생각해 보았습니다. 그러나 클리너가 있고 쉬운 방법이라면 어떤 제안도 크게 감사 할 것입니다. 감사.

가능하면 타사 라이브러리를 사용하지 않는 것이 좋습니다.

+0

http://stackoverflow.com/questions/253556/what-parameter-parser-libraries-are-there-for-c를 참조하십시오. 당연히, 나는 나 자신의 인수 해석 라이브러리도 연결하려고한다 : http://www.taenarum.com/software/dropt/ – jamesdlin

답변

0

가장 깨끗한 방법은 Boost program_options입니다.

+0

어떻게 이런 식으로 구현되는지에 대한 간단한 예제를 줄 수 있겠는가? 또한 Boost 라이브러리의 일부로 다운로드하고 추가해야합니까? – Delete

0

어떻게 gnu cat이 명령 행 옵션을 처리하는지 확인했습니다. 그것은, 지금이 권리를 재미있는 일을 한 것

#include <stdio.h> 

int main (int argc, char *argv) { 
    int c; 
    while ((c = getopt(argc, argv, "abc")) != -1) { 
     switch (c) { 
      case 'a': 
       printf("selected: a\n"); 
       break; 
      case 'b': 
       printf("selected: b\n"); 
       break; 
      case 'c': 
       printf("selected: c\n"); 
       break; 
      default: 
       printf("Usage: cli -a/-b/-c\n"); 
       break; 
     } 
    } 
} 
0

-a CLI -ab 파일 또는 CLI -b -ac 파일 또는 CLI -bc 파일 : 나는 당신 같은 플래그를 전달할 수 있습니다 C. 예를 썼다. 여기서 일반적인 생각 만 설명 할 것입니다. 전체 코드는 현재 500 라인 이상이며, 포맷팅 등을 위해 더 많은 유틸리티를 사용합니다.

예를 들어, 나는 프로그램을 help (이것은 꽤 더미 임)으로 만들고 있습니다.

struct help_opt 
{ 
    string owner; 
    string path; 
    bool rec; 
    int depth; 
    help_opt() : owner(""), path("/"), rec(false), depth(0) { } 
}; 

또 다른 구조체 모델 명령 줄 인수 : 평범 구조체는 프로그램이 기본 값과 함께, 필요한 모든 옵션이 포함되어

struct help_args : public help_opt, public arguments <help_args> 
{ 
    template <typename S> 
    void define(S& s) 
    { 
     set(s, owner, "owner", 'w', "force <name> as owner",   "name"); 
     set(s, path, "output", 'o', "save all output to <path>",  "path"); 
     set(s, rec,  "recurse", 'r', "recurse into sub-topics"); 
     set(s, depth, "depth", 'd', "set <number> as maximum depth", "number"); 
    } 

    string title() const { return "my help"; } 
    string usage() const { return "help [<options>] [<topic>]"; } 

    string info() const 
    { 
     return 
      "Display help on <topic>, " 
      "or list available topics if no <topic> is given."; 
    } 

    help_args(int argc, char* argv[]) : arguments(argc, argv) { } 
}; 

클래스 arguments 내가 필요한 모든 인프라입니다. 메타 데이터 (이름, 약어 등)와 함께 모든 인수는 define()에 정의되어 있으며 각각 set() 메서드를 호출합니다.

인수 s은 다중 작업을 지원하는 데 사용됩니다. 사용자 입력을 수집하거나, 도움말 텍스트를 작성하거나, 사용자가 제공 한 값을 표시 할 수 있습니다. 그런 다음 각 멤버에 대한 참조를 전달합니다. 각 멤버에는 사용자 입력에 따라 적절한 값이 주어 지거나 기본값이 그대로 유지됩니다. 그런 다음 인수 이름, 약어, 전체 도움말 텍스트 및 선택적으로 매개 변수 이름을 따릅니다. 부울 인수는 매개 변수없이 플래그로 별도로 처리됩니다.

추가 방법 title(), info() 등은 프로그램에 대한 맞춤 정보 메시지를 지정합니다.

실제 처리는 arguments의 생성자에 의해 수행됩니다. 이 경우 define()help_args이며, 차례로 set()arguments입니다.각 옵션에 대해 명령 행 입력이 스캔되고 필요에 따라 변수가 갱신됩니다. 동시에, gnu 프로그램에서와 마찬가지로 --help, --usage, --version과 같은 옵션에 대해 메타 데이터가 수집되고 출력이 자동으로 생성됩니다.

argumentshelp_args이 템플릿 매개 변수로 전달된다는 사실은 템플릿이기 때문에 define()을 기본 클래스에서 호출 할 수있게 허용하는 것이므로 가상이 아닙니다. 단일 작업 만 필요한 경우 일반 가상 메서드로 다시 전환 할 수 있습니다.

아주 깨끗합니다. 사용할 수있는 도구와 라이브러리가 많다는 것을 알고 있지만 실제로는이 방법을 선호합니다. 준비가 완료되면 구현을 공유 할 수 있습니다. 거의 완료되었습니다.