2013-06-17 3 views
4

argv에서 명령 줄 인수를 수정하거나 지우고 싶습니다.명령 줄 인수 변경 argv

//Somewhere near the top of main() 

bool itemFound(false); 
for(int i=1; i<argc; ++i) { 
    if(argv[i] == "--item") { 
    itemFound = true; 
    //And remove this item from the list 
    argv[i] = "  "; //Try to remove be just inserting spaces over the arg 
    } 
} 

//Now, use argc/argv as normal, knowing that --item is not in there 

그러나 여전히 --item이 목록에 포함되어 있습니다.

이 작업을 수행하는 가장 좋은 방법은 무엇입니까?

+0

사용의 strcpy (는 argv [I] ' "); –

+0

먼저 데이터 구조를 일종의 데이터 구조에 복사하는 것이 좋습니다. 그렇지 않으면 Nishith의 해결책이 효과가있을 수 있습니다 – woosah

+0

'std :: vector args (argv, argv + argc); ' –

답변

3

디버깅을 시도 했습니까? 그렇게하면 아무 것도 지우려고 시도하지 않는다는 것을 알 수 있습니다. 문자열 (char*)을 단순한 같음과 비교할 수는 없습니다. 사실상 포인터를 비교하고 있기 때문에, 거의 같지 않을 것입니다. 대신,이 같은 문자열 비교 함수를 사용한다 :

if (!strcmp(argv[i], "--item")) { 

을 또한,이 인수를 덮어하고 있기 때문에, 당신은 공간을 많이 사용할 필요가 없습니다, 당신은 단순히 빈 문자열로 설정할 수 있습니다 (argv[i] = "") 또는 기존 문자열을 수정하여 비워 둡니다 (argv[i][0] = 0). 또는 나머지 나머지 인수를 바꿀 수 있으므로 나머지 코드를 혼란스럽게 할 수있는 틈이 생기지 않게됩니다.

+0

예 riv, 확실히 제 문제였습니다. 감사. –

+1

'strcmp'가'int'를 리턴하고'bool'을 리턴하지 않기 때문에 테스트는 매우 혼란 스럽습니다. 더 나은 것은'if (strcmp (argv [i], "--item") == 0)'입니다. –

+1

또한 C 표준에 따르면'argv [i] = ""'는 정의되지 않은 동작입니다. (C++ 표준은 여러분이'argv [i]'를 수정할 수 있는지 여부를 말하지 않지만, 여기서는 C 호환성을 가정 할 것입니다.)이 제한의 이유를 모르겠습니다. 실제로 문제를 일으킬 것이지만 C 표준은 그것이 금지되어 있다고 명시 적으로 말하고있다. –

1

C++을 사용하고 있으므로 std :: string에서 C와 유사한 문자열을 모두 변환 할 수 있습니다. 이 작업은 프로그램 시작시 한 번 수행되므로 효율성 문제는 없습니다.

//Somewhere near the top of main() 

bool itemFound(false); 
for(int i=1; i<argc; ++i) { 
    if(std::string(argv[i]) == std::string("--item")) { 
    itemFound = true; 
    //And remove this item from the list 
    argv[i][0] = 0; //Transform it in an empty string, putting null as first character 
    } 
} 

//Now, use argc/argv as normal, knowing that --item is not in there 

그렇지 않으면 (변수는 argv와 해킹 방지) :

std::vector<std::string> validArgs; 
validArgs.reserve(argc); //Avoids reallocation; it's one or two (if --item is given) too much, but safe and not pedentatic while handling rare cases where argc can be zero 
for(int i=1; i<argc; ++i) { 
    const std::string myArg(argv[i]); 
    if(myArg != std::string("--item")) 
    validArgs.push_back(myArg); 
} 

어떤 이유로 당신은 여전히 ​​itemFound이 필요한 경우는 경우 블록에 설정할 수 있습니다.

(참고 : 하나의 문 블록이있을 때 이것은 앓은 주제 : https://softwareengineering.stackexchange.com/questions/16528/single-statement-if-block-braces-or-no하지만 당신이, 중괄호가 필요하지 않습니다)

편집 (표준 사이의 비교 연산자의 존재를 돌보는 : : 문자열과 문자 *)

bool itemFound(false); 
for(int i=1; i<argc; ++i) { 
    if(std::string("--item") == argv[i]) { 
    itemFound = true; 
    //And remove this item from the list 
    argv[i][0] = 0; //Transform it in an empty string, putting null as first character 
    } 
} 
또는

:

std::vector<std::string> validArgs; 
validArgs.reserve(argc); //Avoids reallocation; it's one or two (if --item is given) too much, but safe and not pedentatic while handling rare cases where argc can be zero 
for(int i=1; i<argc; ++i) 
    if(std::string("--item") != argv[i]) 
    validArgs.push_back(std::string(argv[i])); 
+0

http://coliru.stacked-crooked.com/view?id=f1448c0569a547cd366cdae779d59ab1-f674c1a6d04c632b71a62362c0ccfc51은 흥미 롭습니다. –