2011-01-24 99 views
3

我遇到命令行參數問題。我完成了計劃,所以我可以像這樣的命令行啓動它:自定義命令行參數

program.exe test.txt copy_test.txt 

基本上,我的程序執行以下操作:

  • 輸入一些文本文件
  • 排序,並複製到新的文本文件

但(總是但是?!),我應該啓動該程序的命令行是這樣的:

program.exe -input=test.txt -output=copy_test.txt 

我不知道該怎麼做。我研究,但我沒有發現任何幫助:(

請回復。

#include <string> 
#include <iostream> 
#include <fstream> 
#include <vector> 
#include <algorithm> 
using namespace std; 

int main (int argc, char* argv[]) 
{ 
ifstream in(argv[1]); 
ofstream out(argv[2]); 
vector <string> sV; 
string line; 
while (in >> line) 
    sV.push_back(line); 
for (int i = 0; i < sV.size(); i++) 
sort (sV.begin(), sV.end()); 
for (int i = 0; i < sV.size(); i++) 
out << sV[i] << endl; 
cin.get(); 
return 0; 
} 

回答

0

那麼,你的新格式參數,你不能只是將它們傳遞給流構造函數。

您必須檢查它們是否以特定字符串開頭,例如strncmp,然後將相關位的地址(例如argv[1]+8)作爲輸入類型。

由於您提供了--input=類型的前綴,因此您可能還需要處理它們可能處於其他順序的可能性。

例如,您可以替換:

int main (int argc, char* argv[]) { 
    ifstream in(argv[1]); 
    ofstream out(argv[2]); 

的東西,如:

int main (int argc, char* argv[]) { 
    char *infile = 0; 
    char *outfile = 0; 
    for (int i = 1; i < argc; i++) { 
     if (strncmp (argv[i], "--input=", 8) == 0) { 
      infile = argv[i] + 8; 
     } else { 
      if (strncmp (argv[i], "--output=", 9) == 0) { 
       outfile = argv[i] + 9; 
      } else { 
       std::cerr << "Invalid argument [" << argv[i] << "]" << std::endl; 
       return -1; 
      } 
     } 
    } 
    if ((infile == 0) || (outfile == 0)) { 
     std::cerr << "Need to specify input and output file" << std::endl; 
     return -1; 
    } 

    ifstream in(infile); 
    ofstream out(outfile); 
+0

謝謝。這非常有幫助。 U'r da man:D – 2011-01-24 11:33:41

6

你應該分析mainargv參數,以檢查它們是否開始由-input-output等等等等

從頭開始做,這是一個地獄,但幸運的是有許多有用的庫要做到這一點,像boost.program_options

+0

+1這個庫是一個很好的發現,也是一個很好的方式來表明輪子不必被重新發明。 – jmort253 2011-01-24 10:26:05

0

你可以不再需要爲高級用戶不得不每次運行程序時都鍵入不必要的文本,而是提供一個顯示使用情況的-help開關。

這通常是大多數命令行程序所採取的方法,也是很多命令行愛好者都喜歡命令行的簡單性和強大功能的原因。

另一種選擇是提供兩種方法,因爲有些用戶可能更喜歡較長的方法。

+0

這不是關於輸入較少:選項(以 - 開頭)應該是可選的,而參數(不以 - 開頭)通常是必需的。 – 2011-01-24 10:37:12

0

我有點晚與此聚會,但我會提供更新的答案。實際上,您可以使用'getopt'在C++中獲得所需的功能。使用getopt_long(),您可以創建單個字符選項(如-c)或命名選項(如--input)。您也可以使用getopt_long_only(),這將允許您只通過一個短劃線來傳遞命名選項。例如參見herethis answer

這裏是要做到你想要做什麼的例子:

#include <iostream> 
#include <getopt.h> 
#include <map> 
#include <string> 

int main (int argc, char** argv) 
{ 
    // Create the variables to store your parameters 
    std::map<std::string, std::string> input_parameters ; 
    input_parameters["input"] = "default_in" ; // Storage for input 
    input_parameters["output"] = "default_out" ; // Storage for output 

    // Create variables to hold your parameters 
    const struct option longopts[] = 
    { 
     {"input", required_argument, 0, 'i'}, 
     {"output", required_argument, 0, 'o'}, 
     {0,0,0,0} // This tells getopt that this is the end 
    }; 

    // Some parameters for getopt_long 
    int c(0); 

    // Get the options from the command line 
    while (c != -1) { 
     int option_index(-1) ; 

     // Read the next command line option 
     // Note here that the ':' after the 'i' and 'o' denotes that 
     // it requires an argument 
     c = getopt_long(argc, argv, "i:o:", longopts, &option_index) ; 

     // If the option is valid, fill the corresponding value 
     if ((c>0)&&(option_index>=0)) { 
      std::cout << option_index << std::endl; 
      input_parameters[longopts[option_index].name] = optarg ; 
     } 

     switch (c) { 
      case 'i': 
       // Fill input option 
       input_parameters["input"] = optarg ; 
      case 'o': 
       // Fill output option 
       input_parameters["output"] = optarg ; 
      case '?': 
       // getopt_long printed an error message 
       break ; 
     } 
    } 

    std::cout << "input = " << input_parameters["input"] << std::endl; 
    std::cout << "output = " << input_parameters["output"] << std::endl; 

    return 0 ; 
} 

注意,在這裏,你可以運行這個離開之間的空間參數和你想傳遞給它的值。這將產生如下:

$ ./myscript --input inputfile.txt --output outputfile.txt 
input = inputfile.txt 
output = outputfile.txt 

$ ./myscript -i inputfile.txt -o outpufile.txt 
input = inputfile.txt 
output = outputfile.txt 

您還可以使用--input-i互換(用--output-o下同)。

開始無恥插頭(即圍繞getopt的建立了自己的CLOptions代碼)

我其實有點不滿與工作量也採取了與參數,可能是得到的getopt的完全成熟的功能boolean,double,int或string。我還必須在每個項目中創建一個全新的實現!所以,我把一個名爲「CLOptions」的快速課放在一起,這樣我就可以在我的代碼中使用#include "CLOptions.h"(一切都在一個文件中),現在我只需要一行來定義每個附加選項。它還會創建-h-help選項來爲您打印幫助信息!它包括根據您定義每個參數的方式將每個參數作爲bool,double,int或字符串獲取的功能。你可以在GitHub here上看看它,例如how the above method could be implemented。請注意,該類是C++ 11,編譯時需要-std=c++11(但如果有人問,我可以嘗試編寫C版本)。

雖然我還沒有嘗試過,但還有一些其他人爲解決此問題而設計的其他命令行程序(例如optionsdropt)。你大概可以通過使用Google搜索來找到它們。