My program is supposed to take two required arguments, and three optional arguments, like follows
ATE <input file> <output file> [--threads] [--bass] [--treble]
(note, I haven't figured out how to take <required> arguments yet, so input and output file is defined in the code as -i input_file and -o output_file)
I'm using the GNU library argp to parse the command line arguments, my file is based off the third example.
I run my program using the following command
$ ./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
When running my program, I get "too few arguments", even though argp succesfully parsed the input and output option, as you can see in the output.
Printing out the number of arguments in parse_opt, cout << state->arg_num << endl; gives me 0's at every call.
The code is a little long, but it's completely self-contained so you can compile it to see for yourself.
commands.cpp using namespace std;
#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;
}
				
                        
The options don't count as "arguments" for the context of the argp parser.
When running
./ATE -i input_file.pcm -o output_file.pcm, you have "too few arguments" because you reachARGP_KEY_END, the end of the arguments, with no arguments left.arg_numrepresents the "stand-alone" arguments : the number ofARGP_KEY_ARGarguments that have been processed. You don't have any.To make sure you have the two required arguments as you initialy wanted, check that you don't reach
ARGP_KEY_ENDwithout having seen two arguments (like you are already doing : the too few arguments would mean you don't have your two filenames). Thecase ARGP_KEY_ARGis where you get the values of the arguments.