参数在argv[] 数组中的显示方式取决于所使用的命令外壳。大多数命令 shell 遵循普遍接受的标准,即命令行参数用空格分隔,如果你想用空格指定参数,则必须用引号引起来。
所以./foo -l user1 user2 user3 -name foo是一个命令行,它将作为七个参数提供给C运行时,第一个是程序的名称,其余六个参数是-l、user1、user2、 user3、-name 和 foo。
如果您在命令行输入./foo -l "user1 user2 user3" -name foo,其中用户列表(user1、user2 和 user3)位于带引号的字符串中,则命令行将作为五个参数提供给 C 运行时,第一个是程序的名称,其余四个参数分别为-l、user1 user2 user3(引号通常被命令外壳删除并且都在同一个参数中)、-name 和foo。
回到过去的 UNIX C 命令行实用程序,我们会为简单的命令行解析执行以下操作。以下源代码完成了命令行类可能完成的工作。这是使用 C++ 完成的,但采用 C 风格。
当然,因为这是放在一起的,所以它不是很健壮,例如,特定命令行选项的 30 多个参数会导致问题。
// arglist.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
/*
* argument options accepted are as follows:
* -l -> indicates a user list of one or more user names follows
* -name -> indicates a name for the list follows
*
* arguments without a leading dash are considered to be option changes
* and arguments without a leading dash are considered to be arguments
* for the last option.
**/
typedef struct {
int index;
int argListIndex[30];
} argList;
const int indexOptionUnknown = 0;
const int indexOptionL = 1;
const int indexOptionName = 2;
int main(int argc, char * argv[])
{
// the index into the argv[] array. zeroth element of argve[] is ignored.
argList myList[3] = {0};
int iMyList = 0;
// we skip the first argument which is the name of our program
// we then process the remaining command line arguments which the C runtime
// has provided as a series of char strings.
for (int i = 1; i < argc; i++) {
if (*argv[i] == '-') {
// this is an argument option. figure out which one.
if (strcmp (argv[i], "-l") == 0) {
iMyList = indexOptionL;
} else if (strcmp (argv[i], "-name") == 0) {
iMyList = indexOptionName;
} else {
// unknown option so we will ignore it.
iMyList = indexOptionUnknown;
}
} else {
// this is an argument for the last option found
if (iMyList > indexOptionUnknown) {
myList[iMyList].argListIndex[ myList[iMyList].index ] = i;
myList[iMyList].index++;
}
}
}
std::cout << "option -l, count of arguments " << myList[indexOptionL].index << std::endl;
for (int i = 0; i < myList[indexOptionL].index; i++) {
std::cout << " " << i << " is " << argv[myList[indexOptionL].argListIndex[i]] << std::endl;
}
std::cout << "option -name, count of arguments " << myList[indexOptionName].index << std::endl;
for (int i = 0; i < myList[indexOptionName].index; i++) {
std::cout << " " << i << " is " << argv[myList[indexOptionName].argListIndex[i]] << std::endl;
}
return 0;
}
pgm -l user1 user2 user3 -name foo 等参数行的输出是:
option -l, count of arguments 3
0 is user1
1 is user2
2 is user3
option -name, count of arguments 1
0 is foo
像pgm -l user1 -l user2 -l user3 -name foo 这样的命令行将是相同的输出。该解析器所做的是在命令行上为特定选项构建参数列表。
如果提供了pgm -l "user1 user2 user3" -name foo 等命令行,则输出会因引用的参数而改变,结果为:
option -l, count of arguments 1
0 is user1 user2 user3
option -name, count of arguments 1
0 is foo