精华内容
下载资源
问答
  • 这包括从命令行传递给您程序的 main() 函数的一个整数计数(通常名为 argc)和一个指向字符串的指针数组(通常名为 argv).可以采用两种实质一样的方式声明标注 main() 函数,如清单 1 中所示。 清单 1. ...

    一 命令行

    在编写新程序时,首先遇到的障碍之一就是如何处理控制其行为的命令行参数。这包括从命令行传递给您程序的 main() 函数的一个整数计数(通常名为 argc)和一个指向字符串的指针数组(通常名为 argv).可以采用两种实质一样的方式声明标注 main() 函数,如清单 1 中所示。

    清单 1. 声明 main() 函数的两种方式
    int main( int argc, char *argv[] );
    int main( int argc, char **argv );

    第一种方式使用的是指向 char 指针数组,现在似乎很流行这种方式,比第二种方式(其指针指向多个指向 char 的指针)略微清楚一些。由于某些原因,我使用第二种方式的时间更多一些,这可能源于我在高中时艰难学习 C 指针的经历。对于所有的用途和目的,这两种方法都是一样的,因此可以使用其中您自己最喜欢的方式。

    当 C 运行时库的程序启动代码调用您的 main() 时,已经对命令行进行了处理。argc 参数包含参数的计数值,而 argv 包含指向这些参数的指针数组。对于 C 运行时库,arguments 是程序的名称,程序名后的任何内容都应该使用空格加以分隔。

    例如,如果使用参数 -v bar www.ibm.com 运行一个名为 foo 程序,您的 argc 将设置为 4,argv 的设置情况将如清单 2 中所示。

    清单 2. argv 的内容
    argv[0] - foo
    argv[1] - -v
    argv[2] - bar
    argv[3] - www.ibm.com

    一个程序仅有一组命令行参数,因此我要将此信息存储在记录选项和设置的全局结构中。对程序有意义的要跟踪的任何内容都可以记录到此结构中,我将使用结构来帮助减少全局变量的数量。

    二 getopt函数解析

    getopt被用来解析命令行选项参数。

    #include <unistd.h>
          extern char *optarg;  //选项的参数指针
          extern int optind,   //下一次调用getopt的时,从optind存储的位置处重新开始检查选项。 
          extern int opterr,  //当opterr=0时,getopt不向stderr输出错误信息。
          extern int optopt;  //当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt 中,getopt返回'?’、
          int getopt(int argc, char * const argv[], const char *optstring);
     调用一次,返回一个选项。在命令行选项参数再也检查不到optstring中包含的选项时,返回-1,同时optind储存第一个不包含选项的命令行参数。

    首先说一下什么是选项,什么是参数。

    1.单个字符,表示选项,

    2.单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。
    3 单个字符后跟两个冒号,表示该选项后必须跟一个参数。参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(这个特性是GNU的扩张)。

    例如gcc -g -o test test.c ,其中g和o表示选项,test为选项o的参数。

    上面是getopt()函数的基本含义,大家懂得了这些之后,我们一个例子加深一下理解。

    例如我们这样调用getopt(argc, argv, "ab:c:de::");
    从上面我们可以知道,选项a,d没有参数,选项b,c有一个参数,选项e有有一个参数且必须紧跟在选项后不能以空格隔开。getopt首先扫描argv[1]到argv[argc-1],并将选项及参数依次放到argv数组的最左边,非选项参数依次放到argv的最后边。

    执行程序为:
         0          1    2   3  4   5      6   7     8    9 
    $ ./test file1 -a -b -c code -d file2 -e file3
     扫描过程中,optind是下一个选项的索引, 非选项参数将跳过,同时optind增1。optind初始值为1。当扫描argv[1]时,为非选项参数,跳过,optind=2;扫描到-a选项时,下一个将要扫描的选项是-b,则optind更改为3;扫描到-b选项时,后面有参数(会认为-c为选项b的参数),optind=5,扫描到code非选项跳过optind=6;扫描到-d选项,后面没有参数,optind=7;扫描到file2非选项跳过optind=8;扫描到-e后面本来应该有参数,optind=9但是有空格所以e的参数为空。
     
    扫描结束后,getopt会将argv数组修改成下面的形式
          0       1  2   3   4  5  6       7      8      9
    $ ./test -a -b -c -d -e file1 code file2 file3
    展开全文
  • 为什么需要命令行解析函数? 当一个用C语言编写的Linux或UNIX程序运行时,它是从main...无论操作系统何时启动一个新程序,参数argc和argv都被设置并传递给main。这些参数通常由另一个程序提供,这个程序一般是shell,

    为什么需要命令行解析函数?

    当一个用C语言编写的Linux或UNIX程序运行时,它是从main函数开始的。函数声明可以如下:

    int main(int argc, char *argv[])
    其中argc是程序参数的个数,argv是一个代表参数自身的字符串数组。无论操作系统何时启动一个新程序,参数argc和argv都被设置并传递给main。这些参数通常由另一个程序提供,这个程序一般是shell,它要求操作系统启动该程序。shell接收用户输入的命令行,将命令行分解成单词,然后把这些单词放入argv数组。

    例如,如果我们给shell输入如下命令:

    $./myprog left right 'and center'

    程序myprog将从main函数开始,main的参数值是:

    argc:4    argv:{"myprog", "left", "right", "and center"}

    注意:参数个数包括程序名自身,argv数组也包含程序名并将它作为第一个元素argv[0]。因为我们在shell命令里使用了引号,所以第四个参数是一个包含了空格的字符串。

    在编程的时候,当命令行参数个数较多时,如果按照顺序一个一个定义参数含义很容易造成混乱;如果程序只按顺序处理参数的话,一些“可选参数”的功能将很难实现。为了解决此类问题,GNU C库提供了函数以简化C/C++程序中的解析工作。

    getopt_long(int argc, char* argv[], const char *optstring, const struct option *longopts, int *longindex);

    注意:getopt头文件为unistd.h,getopt_long额外支持长参数解析,头文件为getopt.h

    参数optstring:负责处理短参数。也称为选项指定符字符串,该字符串告诉getopt哪些选项可用,以及它们是否有关联值。optstring只是一个字符列表,每个字符代表一个单字符选项。如果一个字符后面紧跟一个冒号,则表明该选项有一个关联值作为下一个参数。

    例:

    char *optstring = “abcd:”; 
    上面这个optstring在传入之后,getopt函数将依次检查命令行是否指定了 -a, -b, -c及 -d(需要多次调用getopt函数,直到其返回-1),当检查到上面某一个参数被指定时,函数会返回被指定的参数名称(即该字母) 
    最后一个参数d后面带有冒号,:表示参数d是可以指定值的,如 -d 100 或 -d user

    参数longopts负责处理长参数。指向一个由option结构体组成的数组,那个数组的每一个元素都指明了一个长参数(形如”–name”的参数)名称和性质

    struct option {
        const char* name;
        int has_arg;
        int *flag;
        int val;
    }
    struct option的解析:

    name:参数名称

    has_arg:指明是否带参数值,数值可选:

    	no_argument(即 0)表明这个长参数不带参数(即不带数值,如:--name)
    	required_argument (即 1) 表明这个长参数必须带参数(即必须带数值,如:--name Bob)
    	optional_argument(即 2)表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)
    flag:设置为NULL表示当找到该选项时,getopt_long返回在成员val里给出的值。否则,getopt_long返回0,并将val的值写入flag指向的变量。

    val:getopt_long为该选项返回的值。


    参数longindex:如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值。

    外部变量optarg:在getopt_long循环处理选项时,如果选项有一个关联值,则外部变量optarg指向这个值。

    外部变量optind:下一个要读取的参数的下标位置


    test.c 完整范例:

    /*
    在linux下编写的,没安装中文输入法,所以用蹩脚的英文写的注释,懒得删除了
    */
    #include <stdio.h>
    #include <getopt.h>
    
    int main(int argc, char *argv[])
    {
    	/*
    	getopt_long(int argc, char* argv[],
    						 const char* optstring,
    						 const struct option* longopts,
    						 int longindex)
    	*/
    	
    	/*
    	optstring
    	the ':" after char means it can add a argument
    	字符后面的 : 表示后面可以加参数
    	比如 -u 100
    	*/
    	char *optstring = "u:d:l:r:t";
    	
    	int up = 0;
    	int down = 0;
    	int left = 0;
    	int right = 0;
    	int turn = 0;
    
    	/*
    	longopts
    	1. name : argument name
    	2. has_arg : whether need a argument
    	3. flag : when it is NULL,getopt_long() will return the 'val';
    						or getopt_long() will set the flag with 'val
    	4. val : which will use with flag
    	这里就是定义一个结构option数组,
    	第一个参数是名字
    	第二个参数是选择是否需要加参数,选择是了就可以比如 -up 100 
    	第三个参数flag, 如果是空值,getopt_long()就会返回第四个参数val;
    					如果给的有地址,比如&turn,getopt_long()就会把val的值写入这个地址,返回0
    	第四个参数val
    	*/
    	struct option long_opts[] = 
    	{
    		{"up", required_argument, NULL, 'u'},
    		{"down", required_argument, NULL, 'd'},
    		{"left", optional_argument, NULL, 'l'},
    		{"right", required_argument, NULL, 'r'},
    		{"turn", no_argument, &turn, 1},
    		{NULL, no_argument, NULL, 0}  
    	};
    
    	int opt = 0;
    	int options_index = 0;
    
    	/*
    	反复循环来解析参数,getopt_long执行一次会解析一个参数,如果没有参数就返回-1
    	如果该参数有值,比如-u 100,则optarg = 100, optind会指向下一个要解析的参数的数组下标
    	*/
    	while((opt = getopt_long(argc, argv, optstring, long_opts, &options_index)) != EOF)
    	{
    		//optarg is not null
    		if (optarg)
    			printf("opt = %d,optarg = %d,optind = %d\n", opt, atoi(optarg), optind);
    		else
    			printf("opt = %d\n", opt);
    		switch(opt)
    		{
    			case 0 :
    				break;
    			case 'u' : 
    				if(optarg)
    					up = atoi(optarg);
    				break;
    			case 'd' :
    				if(optarg)
    					down = atoi(optarg);
    				break;
    			case 'l' :
    				if(optarg)
    					left = atoi(optarg);
    				break;
    			case 'r' : 
    				if(optarg)
    					right = atoi(optarg);
    				break;
    			case 't' :
    				turn = 1;
    				break;
    		}
    	}
    	if(turn)
    		printf("turn,up %d step,down %d step,left %d step,right %d step\n", up, down, left, right);
    	else
    		printf("no turn,up %d step,down %d step,left %d step,right %d step\n", up, down, left, right);
    }
    运行截图:

    在测试的时候我发现一个问题,把option的has_arg的值设为optional_argument时候,并没有成为可选,而是没法识别后面的参数,大家可以试一下。

    如果有知道为什么的希望可以告知~谢谢!!!

    参考文章:http://blog.csdn.net/feglass/article/details/51468857


    展开全文
  • 当一个用C语言编写的Linux或UNIX程序运行时,它是从main函数开始的。对这些程序而言,main函数的声明...无论操作系统何时启动一个新程序,参数argc和argv都被设置并传递给main。这些参数通常由另一个程序提供,这个程序

    当一个用C语言编写的Linux或UNIX程序运行时,它是从main函数开始的。对这些程序而言,main函数的声明如下所示:

    int main(int argc, char *argv[])

    其中argc是程序参数的个数(int),argv是一个代表参数自身的字符串数组(char **)。无论操作系统何时启动一个新程序,参数argc和argv都被设置并传递给main。这些参数通常由另一个程序提供,这个程序一般是shell,它要求操作系统启动该新程序。shell接收用户输入的命令行,将命令行分解成单词,然后把这些单词放入argv数组。

    例如,如果我们给shell输入如下命令:

    $myprog left right 'and center'

    程序myprog将从main函数开始,main带的参数是:
    argc: 4
    argv: {“myprog”, “left”, “right”, “and center”}
    注意:参数个数包括程序名自身,argv数组也包含程序名并将它作为第一个元素argv[0]。因为我们在shell命令里使用了引号,所以第四个参数是一个包含了空格的字符串。

    人们常常希望使用命令行参数向程序传递信息,许多工具程序也使用命令行参数来改变程序的行为或设置选项。通常,你可以使用以短横线(-)开头的命令行参数来设置这些所谓的标识(flag)或开关(switch)。我们建议在应用程序中,所有的命令行开关都应以一个短横线开头,其后包含单个字母或数字。如果需要,不带后续参数的选项可以在一个短横线后归并到一起,如:ls -lstr。

    在编程的时候,当命令行参数个数较多时,如果按照顺序一个一个定义参数含义很容易造成混乱;如果程序只按顺序处理参数的话,一些“可选参数”的功能将很难实现。为了解决此类问题,GNU C库提供了函数以简化C/C++程序中的解析工作。

    注:Linux系统上可用的C编译器是GNU C编译器,它建立在自由软件基金会的编程许可证的基础上,因此可以自由发布。GNU C 对标准C进行进一步扩展,以增强标准C的功能。函数getopt_long能够同时处理长短两种格式的选项,要使用这个函数,请包含头文件

    getopt_long(int argc, char* argv[], const char *optstring, const struct option *longopts, int *longindex);
    • 参数optstring:负责处理短参数。也称为选项指定符字符串,该字符串告诉getopt哪些选项可用,以及它们是否有关联值。optstring只是一个字符列表,每个字符代表一个单字符选项。如果一个字符后面紧跟一个冒号,则表明该选项有一个关联值作为下一个参数。

    optstring的格式举例说明比较方便,例如:
    char *optstring = “abcd:”;
    上面这个optstring在传入之后,getopt函数将依次检查命令行是否指定了 -a, -b, -c及 -d(这需要多次调用getopt函数,直到其返回-1),当检查到上面某一个参数被指定时,函数会返回被指定的参数名称(即该字母)
    最后一个参数d后面带有冒号,: 表示参数d是可以指定值的,如 -d 100 或 -d user。

    • 参数longopts:负责处理长参数。指向一个由option结构体组成的数组,那个数组的每一个元素都指明了一个长参数(形如”–name”的参数)名称和性质:
     struct option {
                   const char *name;
                   int         has_arg;
                   int        *flag;
                   int         val;
               };

    name:参数名称

    has_arg:指明是否带参数值,其数值可选:

    no_argument(即 0)表明这个长参数不带参数(即不带数值,如:--name)
    required_argument (即 1) 表明这个长参数必须带参数(即必须带数值,如:--name Bob)
    optional_argument(即 2)表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)
    

    flag:设置为NULL表示当找到该选项时,getopt_long返回在成员val里给出的值。否则,getopt_long返回0,并将val的值写入flag指向的变量。

    val:getopt_long为该选项返回的值。

    • 参数longindex:如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值。

    外部变量optarg:在getopt_long循环处理选项时,如果选项有一个关联值,则外部变量optarg指向这个值。


    参考链接:

    [1] http://blog.csdn.net/cashey1991/article/details/7942809

    [2] Linux程序设计(第4版)

    展开全文
  • 我有一个C程序,它公开了一个...然后脚本执行完毕boost::python::exec_file(filename, main_globals, main_globals)要将命令行参数传递给Python脚本,我们必须通过Python C-API函数设置它们PySys_SetArgv(int arg...

    我有一个C程序,它公开了一个

    Python接口来执行用户的嵌入式Python脚本.

    用户插入要运行的Python脚本的路径和命令行参数.

    然后脚本执行完毕

    boost::python::exec_file(filename, main_globals, main_globals)

    要将命令行参数传递给Python脚本,我们必须通过Python C-API函数设置它们

    PySys_SetArgv(int args, char** argv)

    在调用exec_file()之前.

    但是这需要标记包含命令行参数的用户字符串以获取参数列表,然后通过PySys_SetArgv将它们传递回Python解释器.

    这不仅仅是浪费时间,因为这样主要的C程序必须负责对命令行字符串进行标记,而不知道后面的逻辑,这只在自定义用户的脚本中定义.

    在metacode中,更好,更清晰的方法是这样的:

    string command_line_args = '-v -p "filename" -t="anotherfile" --list="["a", "b"]" --myFunnyOpt'

    exec_file( filename, command_line_args, ...)

    我花了几个小时查看Boost和Python C-API文档,但我找不到任何有用的东西.

    你知道是否有办法实现这一点,即传递一整串命令行

    来自C的嵌入式Python脚本的参数?

    更新:

    在我的情况下我用过:

    // defining the separators

    std::string escape_char = "\\"; // the escape character

    std::string sep_char = " "; // empty space as separator

    std::string quote_char = ""; // empty string --> we don't want a quote char'

    boost::escaped_list_separator sep( escape_char, sep_char, quote_char );

    因为我希望能够解析包含字符串的元组,例如:

    '--option-two=("A", "B")'

    如果您使用:

    escaped_list_separator sep('\\', ' ', '"');

    与在原始帖子中一样,您没有正确标记引用的字符串.

    展开全文
  • 命令行参数

    2017-04-12 19:50:10
    给main()函数传递两个参数,int argc和char* argv[] argc:表示命令行参数的个数,不许要用户传递,它会根据用户从命令行输入的参数个数,自动确定 argv[]:存储用户从命令行传递进来的参数,它的第一个成员是用户...
  • 命令行参数是使用 main() 函数参数来处理的,其中,argc 是指传入参数的个数,argv[] 是一个指针数组,指向传递给程序的每个参数。下面是一个简单的实例,检查命令行是否有提供参数,并根据参数执行相应的动作:#...
  • C 命令行参数

    2021-01-03 03:42:53
    命令行参数是使用 main() 函数参数来处理的,其中,argc 是指传入参数的个数,argv[] 是一个指针数组,指向传递给程序的每个参数。下面是一个简单的实例,检查命令行是否有提供参数,并根据参数执行相应的动作: #...
  • C语言命令行参数

    千次阅读 2019-03-16 12:28:27
    命令行参数是使用 main() 函数参数来处理的,其中,argc 是指传入参数的个数,argv[] 是一个指针数组,指向传递给程序的每个参数。下面是一个简单的实例,检查命令行是否有提供参数,并根据参数执行相应...
  • Shell命令行参数

    2019-12-02 08:50:03
    Shell编程中的命令行参数(位置参数)与C程序中的main函数传参类似。这些位置参数使用$N表示,N为正整数,表示命令行传入的第N个参数。N0开始进行标记,与C语言中的数组表示的方式相同。例如,$1表示传递给脚本...
  • C 语言中一个简单的实例检查命令行是否...命令行参数是使用 main) 函数参数来处理的 其中argc 是指传入参数的个数 argv[] 是 一个指针数组指向传递给程序的每个参数下面是一个简单的实例检查命令行是否有 提供参数并根
  • C语言——命令行参数

    2020-05-29 14:39:50
    命令行参数是使用 main() 函数参数来处理的,其中,argc是指传入参数的个数,argv[]是一个指针数组,指向传递给程序的每个参数。下面是一个简单的实例,检查命令行是否有提供参数,并根据参数执行相应的动作: #...
  • C语言 | 命令行参数

    2021-01-04 13:38:52
    命令行参数是使用 main() 函数参数来处理的,其中,argc是指传入参数的个数,argv[]是一个指针数组,指向传递给程序的每个参数。下面是一个简单的实例,检查命令行是否有提供参数,并根据参数执行相应的动作: #...
  • 命令行参数

    2019-03-14 10:27:24
    命令行参数是使用 main() 函数参数来处理的,其中,argc是指传入参数的个数,argv[]是一个指针数组,指向传递给程序的每个参数。下面是一个简单的实例,检查命令行是否有提供参数,并根据参数执行相应的动作: #.....
  • c之命令行参数

    千次阅读 2018-02-09 15:57:17
    命令行参数是使用 main() 函数参数来处理的,其中,argc 是指传入参数的个数,argv[] 是一个指针数组,指向传递给程序的每个参数。下面是一个简单的实例,检查命令行是否有提供参数,并根据参数执行相应的动作:#i...
  • 这两个参数用于在运行程序时,外部程序传递参数,其中argc中保存了参数的个数,argv中分别保存了各个参数.例如一个程序的main()函数头部形如int main(int argc, char *argv[]),编译链接后生成的可执行文件名为a...
  • 32 C语言 - 命令行参数

    2019-10-22 14:37:37
    命令行参数是使用 main() 函数参数来处理的,其中,argc 是指传入参数的个数,argv[] 是一个指针数组,指向传递给程序的每个参数。下面是一个简单的实例,检查命令行是否有提供参数,并根据参数执行相应的动作: #...
  • 命令行参数是使用 main() 函数参数来处理的,其中,argc 是指传入参数的个数,argv[] 是一个指针数组,指向传递给程序的每个参数。下面是一个简单的实例,检查命令行是否有提供参数,并根据参数执行相应的动作: ``...
  • C C++ 命令行参数

    千次阅读 2008-03-29 21:08:00
    可以通过在程序的main()函数中添加形式参数来接收程序在启动时从命令行中获得的各个命令行参数,包括:程序名称、路径、当前环境变量和用户指定参数等。命令行参数由启动程序截获并传递给main()。一个典型的...
  • 命令行参数使用main()函数参数处理,其中argc表示传递参数数量,argv[]是指针数组,指向传递给程序的每个参数。 以下是一个简单的示例,它检查命令行是否提供了任何参数并采取相应的操作 - 1 #...
  • 命令行参数是使用 main() 函数参数来处理的,其中,argc是指传入参数的个数,argv[]是一个指针数组,指向传递给程序的每个参数。 下面是一个简单的实例,检查命令行是否有提供参数,并根据参数执行相应的动作: #...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 151
精华内容 60
关键字:

从命令行给main函数传递参数