Linux下getopt_long函数的使用

getopt_long为解析命令行参数函数,它是Linux C库函数。使用此函数需要包含系统头文件getopt.h。

getopt_long函数声明如下:

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

getopt_long的工作方式与getopt类似,关于getopt的介绍可以参考: https://blog.csdn.net/fengbingchun/article/details/81122843   。但是getopt_long除了接受短选项外还接受长选项,长选项以"--"开头。如果程序只接受长选项,那么optstring应指定为空字符串。如果缩写是唯一的,那么长选项名称可以缩写。长选项可以采用两种形式:--arg=param或--arg param. longopts是一个指针指向结构体option数组。

结构体option声明如下:

struct option {
   const char *name;
   int         has_arg;
   int        *flag;
   int         val;
};

name:长选项的名字

has_arg:0,不需要参数;1,需要参数;2,参数是可选的

flag:指定如何为长选项返回结果。如果flag是null,那么getopt_long返回val(可以将val设置为等效的短选项字符),否则getopt_long返回0.

val:要返回的值。

结构体option数组的最后一个元素必须用零填充

当一个短选项字符被识别时,getopt_long也返回选项字符。对于长选项,如果flag是NULL,则返回val,否则返回0。返回-1和错误处理方式与getopt相同。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

CMakeLists.txt文件内容如下:

PROJECT(samples_cplusplus)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)

# 支持C++11
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O2 -std=c11")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  -g -Wall -O2 -std=c++11")

INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR})

FILE(GLOB samples ${PROJECT_SOURCE_DIR}/*.cpp)

FOREACH (sample ${samples})
	STRING(REGEX MATCH "[^/]+$" sample_file ${sample})
	STRING(REPLACE ".cpp" "" sample_basename ${sample_file})
	ADD_EXECUTABLE(test_${sample_basename} ${sample})
	TARGET_LINK_LIBRARIES(test_${sample_basename} pthread)
ENDFOREACH()

sample_getopt_long.cpp内容如下:

#include <iostream>
#include <getopt.h>
#include <string.h>

int main(int argc, char* argv[])
{
	// reference: http://man7.org/linux/man-pages/man3/getopt.3.html
	int c;
	int digit_optind = 0;

	while (1) {
		int this_option_optind = optind ? optind : 1;
		int option_index = 0;
		static struct option long_options[] = {
			{"add",		required_argument,	0,	0},
			{"append",	no_argument,		0,	0},
			{"delete",	required_argument, 	0,	0},
			{"verbose",	no_argument,		0,	0},
			{"create",	required_argument,	0,	'c'},
			{"file",	required_argument,	0,	0},
			{0,		0,			0,	0}
		};

		c = getopt_long(argc, argv, "abc:d:012", long_options, &option_index);
		if (c == -1) break;

		switch (c) {
		case 0:
			//fprintf(stdout, "option %s ", long_options[option_index].name);
			//if (optarg) fprintf(stdout, "with arg %s", optarg);
			//fprintf(stdout, "\n");

			if (strcmp(long_options[option_index].name, "add") == 0)
				fprintf(stdout, "long option \"add\" value: %s\n", optarg);
			else if (strcmp(long_options[option_index].name, "append") == 0)
				fprintf(stdout, "long option \"append\"\n");
			else if (strcmp(long_options[option_index].name, "delete") == 0)
				fprintf(stdout, "long option \"delete\" value: %s\n", optarg);
			else if (strcmp(long_options[option_index].name, "create") == 0)
				fprintf(stdout, "long option \"create\" value: %s\n", optarg);
			else if (strcmp(long_options[option_index].name, "verbose") == 0)
				fprintf(stdout, "long option \"verbose\"\n");
			else if (strcmp(long_options[option_index].name, "file") == 0)
				fprintf(stdout, "long option \"file\" value: %s\n", optarg);
			break;
		case '0':
		case '1':
		case '2':
			if (digit_optind != 0 && digit_optind != this_option_optind)
				fprintf(stdout, "digits occur in two different argv elements.\n");
			digit_optind = this_option_optind;
			fprintf(stdout, "option %c\n", c);
			break;
		case 'a':
			fprintf(stdout, "option a\n");
			break;
		case 'b':
			fprintf(stdout, "option b\n");
			break;
		case 'c':
			fprintf(stdout, "option c with value '%s'\n", optarg);
			break;
		case 'd':
			fprintf(stdout, "option d with value '%s'\n", optarg);
			break;
		case '?':
			break;
		default:
			fprintf(stdout, "?? getopt returned character code 0%o ??\n", c);
		}	
	}

	if (optind < argc) {
		fprintf(stdout, "non-option argv elements: ");
		while (optind < argc)
			fprintf(stdout, "%s ", argv[optind++]);
		fprintf(stdout, "\n");
	}


	exit(EXIT_SUCCESS);
}

bash.sh内容如下:

#! /bin/bash

real_path=$(realpath $0)
dir_name=`dirname "${real_path}"`
echo "real_path: ${real_path}, dir_name: ${dir_name}"

new_dir_name=${dir_name}/build
mkdir -p ${new_dir_name}
cd ${new_dir_name}
cmake ..
make

cd -

run_getopt_long.sh内容如下:

#! /bin/bash

real_path=$(realpath $0)
dir_name=`dirname "${real_path}"`
echo "real_path: ${real_path}, dir_name: ${dir_name}"

echo -e "\n\ntest argv1:"; ${dir_name}/build/test_sample_getopt_long
echo -e "\n\ntest argv2:"; ${dir_name}/build/test_sample_getopt_long -?
echo -e "\n\ntest argv3:"; ${dir_name}/build/test_sample_getopt_long --add xxx
echo -e "\n\ntest argv4:"; ${dir_name}/build/test_sample_getopt_long -a xx -b yy -c zz -d rr -0 ss -1 tt -2 qq
echo -e "\n\ntest argv5:"; ${dir_name}/build/test_sample_getopt_long --add Tom --append Jim --delete Rucy --verbose XXX --create new_data --file a.txt -ab -c 111 -d 222
echo -e "\n\ntest argv6:"; ${dir_name}/build/test_sample_getopt_long -xxx yyy
echo -e "\n\ntest argv7:"; ${dir_name}/build/test_sample_getopt_long -a

执行过程:首先执行build.sh,然后再执行run_getopt_long.sh即可。

GitHubhttps://github.com/fengbingchun/Linux_Code_Test 

  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`getopt_long` 是一个 C 语言的函数,用于解析命令行参数。与传统的 `getopt` 函数不同,`getopt_long` 支持长选项(如 --help)和短选项(如 -h)。 下面是 `getopt_long` 的基本用法: ```c #include <stdio.h> #include <stdlib.h> #include <getopt.h> int main(int argc, char *argv[]) { int c; int digit_optind = 0; while (1) { int option_index = 0; static struct option long_options[] = { {"add", required_argument, 0, 0 }, {"append", no_argument, 0, 0 }, {"delete", required_argument, 0, 0 }, {"verbose", no_argument, 0, 0 }, {"create", required_argument, 0, 'c'}, {"file", required_argument, 0, 0 }, {0, 0, 0, 0 } }; c = getopt_long(argc, argv, "abc:d:012", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf("option %s", long_options[option_index].name); if (optarg) printf(" with arg %s", optarg); printf("\n"); break; case '0': case '1': case '2': if (digit_optind != 0 && digit_optind != optind) printf("digits occur in two different argv-elements.\n"); digit_optind = 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(EXIT_SUCCESS); } ``` 上面的代码演示了 `getopt_long` 的基本用法。其中 `long_options` 数组定义了长选项的名称、参数类型以及对应的短选项(如果有的话)。在调用 `getopt_long` 函数时,第三个参数为短选项字符串,其中冒号表示该选项需要参数。 函数返回值为下一个选项的字符编码,或者 -1 表示已经解析完所有选项。如果选项需要参数,则该参数存储在全局变量 `optarg` 中。 更多关于 `getopt_long` 的用法,可以参考其官方文档:http://man7.org/linux/man-pages/man3/getopt_long.3.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值