记一次函数异常(getopt_long)

前言

以下参考博客以及man手册。

getopt_long函数,getopt_long函数包含了getopt函数的功能,并且还可以指定“长参数”(或者说长选项),与getopt函数对比,getopt_long比其多了两个参数:

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

在这里,longopts指向的是一个由option结构体组成的数组(数组最后一个成员必须是全0),那个数组的每个元素,指明了一个“长参数”(即形如–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 当这个指针为空的时候,函数直接将val的数值从getopt_long的返回值返回出去,当它非空时,val的值会被赋到flag指向的整型数中,而函数返回值为0
val 用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值。

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

一个小case

// #pragma pack(push, 1)
#include "unistd.h"
#include "getopt.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

void ParserArgs(int argc, char **argv) {
    int opt = 0;
    int longIdx = 0;
    const char *optStr = "h";
    
    static struct option long_options[] = {
        {"proto",  required_argument, NULL, 201},
        {0, 0, 0, 0},
    };
    if (argv[argc-1][0] == '&') {
        argc -= 1;
    }

    while ( (opt = getopt_long(argc, argv, optStr, long_options, &longIdx)) != -1) {
        switch (opt) {
        case 201:
            printf("get %s
", optarg);
            break;
        case 'h':
        case '?':
            printf("aaaa using '-h' to get help");
            exit(0);
        default:
            printf("using '-h' to get help");
            exit(0);
        }
    }

}

int main(int argc, char ** argv) {
    ParserArgs(argc, argv);
    return 0;
} 

看到上面 #pragma pack(push, 1) 没有,如果把这个注掉,运行完美。
但是如果打开就会有段错误。

  • 谁会把对齐写在这?
    • 我觉得这种情况是很有可能发生的。可能你不会写的这么直接,像这个例子一样。但是你可能包含了一个没有闭合对齐的头文件,它产生的结果和这是一样的。
    • 需要检查“pragma pack(push, n)”,“pragma pack(pop)”;“pragma pack(n)”,"pragma pack()"是否匹配。
  • 为什么不闭合对齐会有问题?
    • 我觉得和getopt_long本身有关,其中option参数是个结构指针,对齐会影响函数对参数的解析。
原文地址:https://www.cnblogs.com/sinpo828/p/10678948.html