windows下的getopt/getoptlong函数

您所在的位置:网站首页 getop函数 windows下的getopt/getoptlong函数

windows下的getopt/getoptlong函数

#windows下的getopt/getoptlong函数| 来源: 网络整理| 查看: 265

windows下的getopt/getoptlong函数

getopt/getopt_long函数是GNU C中的函数,在linux编程中很常用到。这里就不介绍了。

windows下没有找到类似的函数,自己写一个又浪费时间,于是乎从glibc中找出来。

这里放出两个版本的下载地址

https://files.cnblogs.com/files/oloroso/getopt--from-glibc-2.15.tar.gz

https://files.cnblogs.com/files/oloroso/getopt-win-from-glibc-2.2.5.tar.gz

下载GLibC源码

首先需要下载glibC的源代码文件,这个文件比较大,但是我们只需要其中的几个文件而已。

如果是后面给出的链接下载的glibc源码包,只需要两个文件。如果是比较新版本的glibc,可能需要四个文件(getopt.h/getopt_int.h/getopt.c/getopt_init.c)

这个只需要图中所示的两个文件即可。下载之后找到这两个文件解压出来即可。

下载地址  http://ftp.ntu.edu.tw/gnu/libc/#glibc-2.2.5.tar.gz

这是glibc-2.2.5的压缩包中间提取的文件

下面是glibc-2.15中需要提取的文件

修改getopt.c gettext.h头文件不存在问题(glibc-2.15)

首先需要修改的是没有“gettext.h”这个头文件的问题。这里直接将其注释掉,然后修改后面的宏定义。

这个修改仅是glibc-2.15版本中,如果是glibc-2.2.5版本的,是没有这个问题的。

将下面的代码(大概在70行)

1 #ifdef _LIBC 2 # include 3 #else 4 # include "gettext.h" 5 # define _(msgid) gettext (msgid) 6 #endif

修改为

1 #ifdef _LIBC 2 # include 3 #else 4 //# include "gettext.h" 5 # define _(msgid) (msgid) 6 #endif

修改后

 

alloca的问题(无法解析的外部符号 _alloca)(glibc-2.15)

关于alloca这个函数,从百度百科中摘抄下来一点。

alloca内存分配函数,与malloc,calloc,realloc类似。但是注意一个重要的区别,_alloca是在栈(stack)上申请空间,用完马上就释放.

包含在头文件malloc.h中.在某些系统中会宏定义成_alloca使用。

在glibc-2.2.5版本是没有这个问题的,这个问题存在于glibc-2.15版本中。

编译生成的时候会报错

1> getopt.c 1>e:\getopt-win\getopt.c(571): warning C4013: “alloca”未定义;假设外部返回 int 1>e:\getopt-win\getopt.c(571): warning C4047: “初始化”:“option_list *”与“int”的间接级别不同 1>getopt.obj : error LNK2019: 无法解析的外部符号 _alloca,该符号在函数 __getopt_internal_r 中被引用

这里保存的原因是alloca这个函数没有定义,那么我们使用已经定义好的版本就是了。修改成如下图所示即可

 

strings.h头文件不存在问题(glibc-2.2.5)

这个修改和前面的gettext.h文件的修改类似,但是区别是这个问题在glibc-2.15中不存在。

这里的修改很简单,添加一个 HAVE_STRING_H 的宏定义即可。

修改前                                                                      修改后

  添加getopt_long/getopt_long_only的定义

这两个函数在getopt.h文件中声明了,但是其定义在getopt1.c中,可以直接将getopt1.c文件也拿过来用。因为这个文件中的内容不多,为了减少文件的数量,直接将其中有用的部分拷贝到getopt.c文件中是个不错的主意。

glibc-2.2.5版本中,要拷贝的内容如下

1 int 2 getopt_long (argc, argv, options, long_options, opt_index) 3 int argc; 4 char *const *argv; 5 const char *options; 6 const struct option *long_options; 7 int *opt_index; 8 { 9 return _getopt_internal (argc, argv, options, long_options, opt_index, 0); 10 } 11 12 /* Like getopt_long, but '-' as well as '--' can indicate a long option. 13 If an option that starts with '-' (not '--') doesn't match a long option, 14 but does match a short option, it is parsed as a short option 15 instead. */ 16 17 int 18 getopt_long_only (argc, argv, options, long_options, opt_index) 19 int argc; 20 char *const *argv; 21 const char *options; 22 const struct option *long_options; 23 int *opt_index; 24 { 25 return _getopt_internal (argc, argv, options, long_options, opt_index, 1); 26 }

 

如果是glibc-2.15版本的,除了这两个函数之外,还有两个可重入版本的可以添加进去

1 int 2 getopt_long(int argc, char *const *argv, const char *options, 3 const struct option *long_options, int *opt_index) 4 { 5 return _getopt_internal(argc, argv, options, long_options, opt_index, 0, 0); 6 } 7 8 int 9 _getopt_long_r(int argc, char *const *argv, const char *options, 10 const struct option *long_options, int *opt_index, 11 struct _getopt_data *d) 12 { 13 return _getopt_internal_r(argc, argv, options, long_options, opt_index, 14 0, d, 0); 15 } 16 17 /* Like getopt_long, but '-' as well as '--' can indicate a long option. 18 If an option that starts with '-' (not '--') doesn't match a long option, 19 but does match a short option, it is parsed as a short option 20 instead. */ 21 22 int 23 getopt_long_only (int argc, char *const *argv, const char *options, 24 const struct option *long_options, int *opt_index) 25 { 26 return _getopt_internal (argc, argv, options, long_options, opt_index, 1, 0); 27 } 28 29 int 30 _getopt_long_only_r(int argc, char *const *argv, const char *options, 31 const struct option *long_options, int *opt_index, 32 struct _getopt_data *d) 33 { 34 return _getopt_internal_r(argc, argv, options, long_options, opt_index, 35 1, d, 0); 36 }

 

测试一下

经过上面的修改,可以进行一点简单的测试了。

测试用例不用自己写了,在getopt.c和getopt1.c文件中都有,直接拿过来用了。

这里测试的时候没有区分是glibc-2.2.5还是glibc-2.15版本的getopt/getopt_long,因为两个测试的结果是一样的。

getopt()函数的测试

测试代码

1 #include "getopt.h" 2 #include 3 #include 4 5 int 6 main(int argc, char **argv) 7 { 8 int c; 9 int digit_optind = 0; 10 11 while (1) 12 { 13 int this_option_optind = optind ? optind : 1; 14 15 c = getopt(argc, argv, "abc:d:0123456789"); 16 if (c == -1) 17 break; 18 19 switch (c) 20 { 21 case '0': 22 case '1': 23 case '2': 24 case '3': 25 case '4': 26 case '5': 27 case '6': 28 case '7': 29 case '8': 30 case '9': 31 if (digit_optind != 0 && digit_optind != this_option_optind) 32 printf("digits occur in two different argv-elements.\n"); 33 digit_optind = this_option_optind; 34 printf("option %c\n", c); 35 break; 36 case 'a': 37 printf("option a\n"); 38 break; 39 case 'b': 40 printf("option b\n"); 41 break; 42 case 'c': 43 printf("option c with value '%s'\n", optarg); 44 break; 45 case '?': 46 break; 47 default: 48 printf("?? getopt returned character code 0%o ??\n", c); 49 } 50 } 51 52 if (optind


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3