c++ - GNU argp "too few arguments"

标签 c++ gnu glibc

我的程序应该有两个必需参数和三个可选参数,如下所示

ATE <input file> <output file> [--threads] [--bass] [--treble]

(注意,我还没有弄清楚如何使用 <required> 参数,所以输入和输出文件在代码中定义为 -i input_file 和 -o output_file)

我正在使用 GNU 库 argp 来解析命令行参数,我的文件基于 third example .

我使用以下命令运行我的程序

$ ./ATE -i input_file.pcm -o output_file.pcm
Too few arguments!
Usage: ATE [OPTION...]
            -p AMOUNT_OF_THREADS -b BASS_INTENSITY -t TREBLE_INTENSITY
            input_file.pcm output_file.pcm
Try `ATE --help' or `ATE --usage' for more information.
threads: 2, bass: 4, treble: 4
opening file input.pcm
RUNNING!
done, saving to out.pcm

当运行我的程序时,我得到“参数太少”,即使 argp 成功解析了输入和输出选项,正如您在输出中看到的那样。

打印出 parse_opt 中参数的数量,cout << state->arg_num << endl;每次通话都给我 0。

代码有点长,但是它是完全独立的,所以你可以编译它自己看看。

命令.cpp 使用命名空间标准;

#include <stdlib.h>
#include <argp.h>
#include <iostream>
#include <string>
#include <errno.h>

struct arguments {
    string input_file;
    string output_file;
    int threads;
    int bass;
    int treble;
};

static char doc[] = "Parallequaliser - a multithreaded equaliser application written in c++";
static char args_doc[] = "-p AMOUNT_OF_THREADS -b BASS_INTENSITY -t TREBLE_INTENSITY input_file.pcm output_file.pcm";

static struct argp_option options[] = {
  {"input_file",  'i', "IN_FILE",           0,                   "an input file in pcm format"},
  {"output_file", 'o', "OUT_FILE",          0,                   "an output file in pcm format"},
  {"threads",     'p', "AMOUNT_OF_THREADS", OPTION_ARG_OPTIONAL, "amount of threads, min 2"},
  {"bass",        'b', "BASS_INTENSITY",    OPTION_ARG_OPTIONAL, "bass intensity, from 0 to 7"},
  {"treble",      't', "TREBLE_INTENSITY",  OPTION_ARG_OPTIONAL, "treble intensity, from 0 to 7"},
  {0}
};

static error_t parse_opt (int key, char *arg, struct argp_state *state) {
    struct arguments *arguments = (struct arguments *) state->input;

    switch (key) {
        case 'p':
            if (arg == NULL) {
                arguments->threads = 4;
            } else {
                arguments->threads = strtol(arg, NULL, 10);
            }
            break;
        case 'b':
            if (arg == NULL) {
                arguments->bass = 4;
            } else {
                arguments->bass = strtol(arg, NULL, 10);
            }
            break;
        case 't':
            if (arg == NULL) {
                arguments->treble = 4;
            } else {
                arguments->treble = strtol(arg, NULL, 10);
            }
            break;
        case 'i':
            if (arg == NULL) {
                cout << "You forgot to specify the input file using the -i input_file.pcm option" << endl;
            } else {
                arguments->input_file = (string) arg;
            }
            break;
        case 'o':
            if (arg == NULL) {
                cout << "You forgot to specify the out file using the -i output_file.pcm option" << endl;
            } else {
                arguments->output_file = (string) arg;
            }
            break;
        case ARGP_KEY_ARG:
            cout << "Key arg... " << key << endl;
            if (state->arg_num > 5){
                cout << "Too many arguments!" << endl;
                argp_usage(state);
            }
            break;
        case ARGP_KEY_END:
            if (state->arg_num < 2){
                cout << "Too few arguments!" << endl;
                argp_usage(state);
            }
            break;

            default:
                return ARGP_ERR_UNKNOWN;
    }


    return 0;
}

static struct argp argp = { options, parse_opt, args_doc, doc };

int main (int argc, char **argv) {
    struct arguments arguments;

    arguments.threads  = 2;
    arguments.bass     = 4;
    arguments.treble   = 4;

    argp_parse(&argp, argc, argv, ARGP_NO_EXIT, 0, &arguments);

    cout << "threads: " << arguments.threads << ", bass: " << arguments.bass << ", treble: " << arguments.treble << endl;
    cout << "opening file " << arguments.input_file << endl;
    cout << "RUNNING!" << endl;
    cout << "done, saving to " << arguments.output_file << endl;

    return 0;
}

最佳答案

这些选项不算作 argp 解析器上下文的“参数”。

当运行 ./ATE -i input_file.pcm -o output_file.pcm 时,你有“参数太少”,因为你到达了 ARGP_KEY_END,参数的末尾, 没有参数。 arg_num表示“独立”参数:已处理的 ARGP_KEY_ARG 参数的数量。你没有。

为了确保您拥有最初想要的两个必需参数,请检查您是否在没有看到两个参数的情况下到达ARGP_KEY_END(就像您已经在做的那样:参数太少意味着你没有你的两个文件名)。 case ARGP_KEY_ARG是获取参数值的地方。

关于c++ - GNU argp "too few arguments",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31056266/

相关文章:

c - 需要 __alignof__ 的调试符号

c++ - 用于为 C/C++/脚本代码着色的优秀 WordPress 扩展是什么?

c++ - 如果 GCC 4.4.7 上未使用返回值,则强制调用类运算符 == 失败

linux - 如何确定 glibc 库的安装版本?

awk - 为什么 '-1' 在 Awk 中不起作用,而 '(-1)' 却可以?

linux - 在汇编中使用 printf 会导致管道传输时输出为空,但可以在终端上使用

c++ - 带有堆的 Bellman-Ford 不适用于自定义比较功能

C++ 标准特性和二进制大小

c - 如何理解 GNU 源代码?

c - 为什么在 glibc 引用中测试 int 的符号被称为 "sloppy code"?