Search code examples
c++command-line-argumentsargvgetoptargc

Command line argument option with number offset


I want to ensure that the option/ argument after -f is a number between 0-9. There must be 10 arguments, in total, in any order. The only condition is that -f must be followed by a digit.

/* Ensure that the -f option is included in the arguments
and it is preceeded by valid digit between 0 -9 */
int Crypto::offsetValidation( int argc, char *argv[] )
{
    for( int i = 0; i < argc; i++ )
    {
        if(argv[i] == string("-f"))             
        {           
            cout << "offset" << endl;           
            return offset;
        }       
    }   

    cout << "Usage: -f is required for offset" << endl;
    exit(EXIT_FAILURE);

    return 0;   
}

Solution

  • Transcribing comments into an answer

    Use getopt() , then check that what it points to with optarg is a single-digit number (strlen(optarg) == 1 && isdigit(optarg[0])). Ad hoc argument parsing will get you into all sorts of ad hoc problems.

    How do I ensure that it is right after the " -f " option though…

    You can write code similar to the following:

    int opt;
    while ((opt = getopt(argc, argv, "f:")) != -1)
    {
        switch (opt)
        {
        case 'f':
            if (strlen(optarg) == 1 && isdigit(optarg[0]))
                f_value = optarg[0] - '0';
            else
                err_exit("Invalid value '%s' for -f option", optarg);
            break;
        default:
            …usage error and exit…;
            break;
        }
    }
    

    You can't guarantee that you have -f3 or whatever, but your original string compare would not have allowed that. With getopt(), you're guaranteed that if you have -f3 or -f 3 on the command line, then strcmp(optarg, "3") == 0. I'm blithely assuming you only have -f arguments; you'd need more code to handle the others, whatever they are. You need to add the extra option letters to the string currently containing "f:", and extra cases to the switch, and the variables to handle them.

    I should also add that this is C code that can be compiled by C++ rather than 'real C++'. There's a Boost library for parsing options in C++ that may be a better choice — if you're allowed to use Boost in your project. There are also many other option parsers in general. The GNU getopt_long() is also widely used for long option name parsing (--file name-of-file etc).