windows下的getopt/getoptlong函数

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

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

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

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

http://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://down1.chinaunix.net/distfiles/glibc-2.2.5.tar.bz2

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

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

修改getopt.c

gettext.h头文件不存在问题(glibc-2.15

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

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

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

 #ifdef _LIBC
# include <libintl.h>
#else
# include "gettext.h"
# define _(msgid) gettext (msgid)
#endif

修改为

 #ifdef _LIBC
# include <libintl.h>
#else
//# include "gettext.h"
# define _(msgid) (msgid)
#endif

修改后

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

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

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

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

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

编译生成的时候会报错

>  getopt.c
>e:\getopt-win\getopt.c(): warning C4013: “alloca”未定义;假设外部返回 int
>e:\getopt-win\getopt.c(): warning C4047: “初始化”:“option_list *”与“int”的间接级别不同
>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版本中,要拷贝的内容如下

 int
getopt_long (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, );
} /* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */ int
getopt_long_only (argc, argv, options, long_options, opt_index)
int argc;
char *const *argv;
const char *options;
const struct option *long_options;
int *opt_index;
{
return _getopt_internal (argc, argv, options, long_options, opt_index, );
}

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

 int
getopt_long(int argc, char *const *argv, const char *options,
const struct option *long_options, int *opt_index)
{
return _getopt_internal(argc, argv, options, long_options, opt_index, , );
} int
_getopt_long_r(int argc, char *const *argv, const char *options,
const struct option *long_options, int *opt_index,
struct _getopt_data *d)
{
return _getopt_internal_r(argc, argv, options, long_options, opt_index,
, d, );
} /* Like getopt_long, but '-' as well as '--' can indicate a long option.
If an option that starts with '-' (not '--') doesn't match a long option,
but does match a short option, it is parsed as a short option
instead. */ int
getopt_long_only (int argc, char *const *argv, const char *options,
const struct option *long_options, int *opt_index)
{
return _getopt_internal (argc, argv, options, long_options, opt_index, , );
} int
_getopt_long_only_r(int argc, char *const *argv, const char *options,
const struct option *long_options, int *opt_index,
struct _getopt_data *d)
{
return _getopt_internal_r(argc, argv, options, long_options, opt_index,
, d, );
}

测试一下

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

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

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

getopt()函数的测试

测试代码

 #include "getopt.h"
#include <stdlib.h>
#include <stdio.h> int
main(int argc, char **argv)
{
int c;
int digit_optind = ; while ()
{
int this_option_optind = optind ? optind : ; c = getopt(argc, argv, "abc:d:0123456789");
if (c == -)
break; switch (c)
{
case '':
case '':
case '':
case '':
case '':
case '':
case '':
case '':
case '':
case '':
if (digit_optind != && digit_optind != this_option_optind)
printf("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf("option %c\n", c);
break;
case 'a':
printf("option a\n");
break;
case 'b':
printf("option b\n");
break;
case 'c':
printf("option c with value '%s'\n", optarg);
break;
case '?':
break;
default:
printf("?? getopt returned character code 0%o ??\n", c);
}
} if (optind < argc)
{
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
} exit();
}

测试结果

getopt_long的测试

 #include "getopt.h"
#include <stdlib.h>
#include <stdio.h>
int
main(argc, argv)
int argc; //这是早期的C语言函数参数的写法
char **argv; //现在不提倡这么写
{
int c;
int digit_optind = ; while ()
{
int this_option_optind = optind ? optind : ;
int option_index = ;
static struct option long_options[] =
{
{ "add", , , },
{ "append", , , },
{ "delete", , , },
{ "verbose", , , },
{ "create", , , },
{ "file", , , },
{ , , , }
}; c = getopt_long(argc, argv, "abc:d:0123456789",
long_options, &option_index);
if (c == -)
break; switch (c)
{
case :
printf("option %s", long_options[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
break; case '':
case '':
case '':
case '':
case '':
case '':
case '':
case '':
case '':
case '':
if (digit_optind != && digit_optind != this_option_optind)
printf("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf("option %c\n", c);
break;
case 'a':
printf("option a\n");
break;
case 'b':
printf("option b\n");
break;
case 'c':
printf("option c with value `%s'\n", optarg);
break;
case 'd':
printf("option d with value `%s'\n", optarg);
break;
case '?':
break;
default:
printf("?? getopt returned character code 0%o ??\n", c);
}
} if (optind < argc)
{
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
} exit();
}

测试结果

windows下的getopt/getoptlong函数的更多相关文章

  1. windows下的getopt/getoptlong函数(拷贝GNU C的库函数)

    http://www.cnblogs.com/oloroso/p/4856104.html

  2. [笔记]linux下和windows下的 创建线程函数

    linux下和windows下的 创建线程函数 #ifdef __GNUC__ //Linux #include <pthread.h> #define CreateThreadEx(ti ...

  3. 一个简单的Windows下的socket程序

    服务器端代码server.cpp: #include <stdio.h> #include <WinSock2.h> #pragma comment(lib,"ws2 ...

  4. 【转载】c/c++在windows下获取时间和计算时间差的几种方法总结

    一.标准C和C++都可用 1.获取时间用time_t time( time_t * timer ),计算时间差使用double difftime( time_t timer1, time_t time ...

  5. windows下实现微秒级的延时

    windowsintegeriostream汇编嵌入式任务 最近正在做一个嵌入式系统,是基于windows ce的,外接硬件的时序要微秒级的延时.1.微秒级的延时肯定不能基于消息(SetTimer函数 ...

  6. 使用cygwin移植Linux的项目到Windows下之总结(转)

    使用cygwin移植Linux的项目到Windows下之总结(转) 原文 http://my.oschina.net/michaelyuanyuan/blog/68615?p=1   一.why   ...

  7. c/c++在windows下获取时间和计算时间差的几种方法总结 【转】

    http://blog.csdn.net/coder_xia/article/details/6566708 一.标准C和C++都可用 1.获取时间用time_t time( time_t * tim ...

  8. c和c++在windows下获取时间和计算时间差的方法总结

    c/c++在windows下获取时间和计算时间差的几种方法总结 一.标准C和C++都可用 1.获取时间用time_t time( time_t * timer ),计算时间差使用double diff ...

  9. Linux c 下使用getopt()函数

    命令行参数解析函数 —— getopt() getopt()函数声明如下: #include <unistd.h> int getopt(int argc, char * const ar ...

随机推荐

  1. 自然语言20.1 WordNet介绍和使用 _

    http://blog.csdn.net/ictextr9/article/details/4008703 Wordnet是一个词典.每个词语(word)可能有多个不同的语义,对应不同的sense.而 ...

  2. Foundation框架—— 数组 (NSArray NSMutableArray )

    基础知识回顾 1.在给可变数组添加元素时,要保证该数组已被初始化 2.在遍历可变数组时,不能对其进行增删改 3.NSMutableArray继承自NSArray,几乎拥有NSArray的一切方法. 4 ...

  3. 9月5日网页基础知识 通用标签、属性(body属性、路径、格式控制) 通用标签(有序列表、无序列表、常用标签)(补)

    网页基础知识 一.HTML语言 HTML语言翻译汉语为超文本标记语言. 二.网页的分类 1.静态页面:在静态页面中修改网页内容实际上就是修改网页原代码,不能从后台操作,数据来只能来源于原于代码.静态网 ...

  4. Runner之记计帐项目的典型用户和用户场景

    项目任务:编写日历选择界面和查明细界面(查看某一天的具体收支出状况) 1.背景 ①典型用户 (1)姓名:张云 (2)年龄:17~23 (3)收入:家长给的生活费与自己兼职(1500元/月) (4)代表 ...

  5. Vim以及Terminal 配色方案---"Solarized"配色

    linux用户给vim 以及terminal的配色方案---Solarized配色 官网地址:http://ethanschoonover.com/solarized 看这配色:八卦乾坤,赏心悦目,高 ...

  6. JAVA属性和成员的可见性

  7. C++中const 的各种用法

    C++中const 关键字的用法 const修饰变量 const 主要用于把一个对象转换成一个常量,例如: ; size = ; // error: assignment of read-only v ...

  8. YII2项目常用技能知识总结

    1.不通过日志获取AR执行的原生SQL语句和打印变量数据 $query = User::find() ->select(['username'])->where(['id'=>[1, ...

  9. smarty string_format用法 取小数点后2位

    <{if $d.ul_pv}> <{$d.sum/$d.ul_pv|string_format:'%.2f'}> <{else}> 0.00 <{/if}&g ...

  10. ie下获取上传文件全路径

    ie下获取上传文件全路径,3.5之后的火狐是没法获取上传文件全路径的 /*获取上传文件路径*/ function getFilePath(obj) { var form = $(this).paren ...