[英]Command line parsing in argc/argv
我有以下代碼:
void parse(char *commandLine) {
int rc = 0;
int argc = 0;
char *cmdLine;
char *argv[MAX_ARGS];
filename = NULL;
stdoutFilename = NULL;
stderrFilename = NULL;
cmdLine = strdup(commandLine);
char *param = strtok(cmdLine, " ");
while (param && argc < MAX_ARGS) {
argv[argc++] = param;
param = strtok(NULL, " ");
printf("%s\n", argv[argc-1]);
}
free(cmdLine);
scanOptions(argc, argv);
printf("Filename %s\n", filename);
...
和
void scanOptions(int argc, char *argv[]) {
int c ;
while ((c = getopt (argc, argv, "Df:e:o:")) != -1) {
switch (c) {
case 'D': __debug = 1; break;
case 'f': filename = strdup(optarg); break;
case 'o': stdoutFilename = strdup(optarg); break;
case 'e': stderrFilename = strdup(optarg); break;
default: fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
}
}
}
filename, stdoutFilename
和stderrFilename
是全局變量。 如果我將解析方法稱為:
parse("-ftest/testfile.txt") the variable filename is not set and the call to
printf("Filename %s\n", filename); prints "Filename (null)".
怎么了
有一些錯誤,這可能是也可能不是您的問題的原因:
使用釋放的內存
free(cmdLine);
scanOptions(argc, argv);
您不能在此處釋放cmdLine,因為您的strtok()調用會將cmdLine中的指針分配給argv。 free()在scanOptions()之后,盡管如果直接保存任何optarg指針,它們將指向您具有free()的空間-您使用strdup()可以確保您的情況安全。
重置getopt()
如果以前調用過getopt,則需要重置其一些變量,以便它可以再次掃描(有關說明,請參見getopt聯機幫助頁)。 您需要做:
optind = 0;
argv中的索引錯誤argv中的第一個索引按照慣例是程序名稱,而不是任何程序參數。 因此,請確保您的argv [0]不是您的任何參數。 但是它必須是有效的字符串,而不是NULL指針。
argv [1]應該是第一個參數。
將哨兵添加到argv
main()的傳統argv以NULL指針結尾,您仿真的argv也應該如此。 在while循環之后,執行
argv[argc] = NULL;
getopt(3)
認為argv[0]
是程序名稱,因此只會解析argv[1]
, argv[2]
等的參數。
要使其工作,請在構建臨時數組時在parse()
中將argc
初始化為1
:
int argc = 1;
我無法在您的信息中添加評論。 但我想知道以下內容:
為什么不能直接從Main調用scanOptions()?
scanOptions(argc,argv);
getopt
期望參數從索引1
開始存儲在argv
。
約定名稱為argv[0]
。
因此,您可能希望更改以下代碼:
int argc = 0;
成為:
int argc = 1;
我添加了正確的代碼段以供參考:
char *param = strtok(cmdLine, " ");
argv[argc++] = "dummy";
while (param && argc < MAX_ARGS) {
argv[argc++] = param;
param = strtok(NULL, " ");
}
scanOptions(argc, argv);
free(cmdLine);
解決方案是添加argv [argc ++] =“ dummy”; 填充argv [0]並在scanOptions之后調用free(cmdLine)。
這遠非復雜而錯誤的說法。 您無法維持這一點。 使用boost :: program_options代替。
它看起來像:
namespace po = boost::program_options;
boost::program_options::variables_map vars;
po::options_description options("Command line options");
options.add_options()
("help", "display this help message and exit")
("in", po::value<std::string>()->default_value("file1.txt"), "input file")
("out", "output file");
po::store(po::parse_command_line(argc, argv, options), vars);
po::notify(vars);
std::string infile = vars["in"].as<std::string>();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.