使用 getopt() 解析多个参数

问题描述 投票:0回答:1

我正在开发一个简单的十进制到十六进制/二进制计算器,它将使用命令行参数来指定要转换为哪个,-x 表示十六进制,-b 表示二进制。我正在使用 getopt() 来解析值。

我遇到了几个问题,即如何在一个选项后处理多个参数。我的代码(截至目前)如下

int main(int argc, char *argv[]){  
    int opt;
    int num;
    while((opt = getopt(argc, argv, ":x:b:")) != -1){
        switch(opt){
            case 'x':
                num = atoi(optarg);
                dec_to_hex(num);
                break;
            case 'b':
                num = atoi(optarg);
                dec_to_bin(num);
                break;
            case'?':
                print_usage();
                break;
            case ':':
                print_usage();
                break;
            default:
                print_usage();
        }

    }
    return 0;
}

例如,如果我打电话给

./a.out -b 1234 4321
我想首先调用我的 dec_to_bin 函数 1234,然后调用 4321。 如果没有给出/不正确的选项,我还想打印用法。如果我调用
./a.out 1234
./a.out -x -p 1234
,它应该打印用法。

我尝试在像这样的 switch 语句情况下使用 while 循环,

case 'x':
    while(optind < argc){
        num = atoi(argv[optind++]);
        dec_to_hex(num);
    }

但这仍然只会打印第一次转换。我还认为返回“?”、“:”或默认值将覆盖我不正确/未给出的选项。我很困惑,希望得到任何帮助。谢谢!

c command-line command-line-arguments getopt
1个回答
0
投票

选项通常只接受零个或一个参数。对于您的代码,您确实需要设置程序运行模式的选项;为此,您不需要选项的参数。决定操作模式后,您可以迭代所有非选项参数,执行适当的转换。

类似这样的:

#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>

#define CONV_DEC_TO_HEX 0
#define CONV_DEC_TO_BIN 1

char *prog_name;

void dec_to_hex(int num) {
    printf("convert %d to hex\n", num);
}

void dec_to_bin(int num) {
    printf("convert %d to bin\n", num);
}

void print_usage(FILE *out) {
    fprintf(out, "usage: %s [-xb] arg1 [...argn]\n", prog_name);
}

int main(int argc, char *argv[]){  
    int opt;
    int num;
    int conv = -1;

    prog_name = argv[0];

    while((opt = getopt(argc, argv, "hxb")) != -1){
        switch(opt){
            case 'x':
                conv = CONV_DEC_TO_HEX;
                break;
            case 'b':
                conv = CONV_DEC_TO_BIN;
                break;
            case 'h':
                print_usage(stdout);
                exit(0);
            default:
                print_usage(stderr);
                exit(2);
        }
    }

    if (conv == -1) {
        fprintf(stderr, "ERROR: please select one of -x or -b\n");
        print_usage(stderr);
        exit(2);
    }

    for (int i=optind; i<argc; i++) {
        int arg = atoi(argv[i]);
        switch(conv) {
            case CONV_DEC_TO_HEX:
                dec_to_hex(arg);
                break;
            case CONV_DEC_TO_BIN:
                dec_to_bin(arg);
                break;
        }
    }

    return 0;
}

毫无争议:

$ ./calc
ERROR: please select one of -x or -b
usage: ./calc [-xb] arg1 [...argn]

参数无效:

$ ./calc -z
./calc: invalid option -- 'z'
usage: ./calc [-xb] arg1 [...argn]

有有效的论据:

$ ./calc -x 123 234 345
convert 123 to hex
convert 234 to hex
convert 345 to hex
$ ./calc -b 123 234 345
convert 123 to bin
convert 234 to bin
convert 345 to bin

和所有好的程序一样,请求帮助(使用

./calc -h
)输出到 stdout 而不是 stderr

© www.soinside.com 2019 - 2024. All rights reserved.