Linux下getopt_long函数的使用
getopt_long為解析命令行參數(shù)函數(shù),它是Linux C庫函數(shù)。使用此函數(shù)需要包含系統(tǒng)頭文件getopt.h。
getopt_long函數(shù)聲明如下:
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);
getopt_long的工作方式與getopt類似,關(guān)于getopt的介紹可以參考: https://blog.csdn.net/fengbingchun/article/details/81122843?? 。但是getopt_long除了接受短選項外還接受長選項,長選項以"--"開頭。如果程序只接受長選項,那么optstring應(yīng)指定為空字符串。如果縮寫是唯一的,那么長選項名稱可以縮寫。長選項可以采用兩種形式:--arg=param或--arg param. longopts是一個指針指向結(jié)構(gòu)體option數(shù)組。
結(jié)構(gòu)體option聲明如下:
struct option {const char *name;int has_arg;int *flag;int val;
};
name:長選項的名字
has_arg:0,不需要參數(shù);1,需要參數(shù);2,參數(shù)是可選的
flag:指定如何為長選項返回結(jié)果。如果flag是null,那么getopt_long返回val(可以將val設(shè)置為等效的短選項字符),否則getopt_long返回0.
val:要返回的值。
結(jié)構(gòu)體option數(shù)組的最后一個元素必須用零填充。
當(dāng)一個短選項字符被識別時,getopt_long也返回選項字符。對于長選項,如果flag是NULL,則返回val,否則返回0。返回-1和錯誤處理方式與getopt相同。
下面是從其他文章中copy的測試代碼,詳細內(nèi)容介紹可以參考對應(yīng)的reference:
CMakeLists.txt文件內(nèi)容如下:
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內(nèi)容如下:
#include <iostream>
#include <getopt.h>
#include <string.h>int main(int argc, char* argv[])
{// reference: http://man7.org/linux/man-pages/man3/getopt.3.htmlint 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內(nèi)容如下:
#! /bin/bashreal_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 ..
makecd -
run_getopt_long.sh內(nèi)容如下:
#! /bin/bashreal_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
執(zhí)行過程:首先執(zhí)行build.sh,然后再執(zhí)行run_getopt_long.sh即可。
GitHub: https://github.com/fengbingchun/Linux_Code_Test?
總結(jié)
以上是生活随笔為你收集整理的Linux下getopt_long函数的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下getopt函数的使用
- 下一篇: C++中标准模板库std::vector