Passing arguments and parameters

Hi!

I do not understand how to pass both arguments and parameters to a c++ script.
I want to let the final user to use my script in the following way:

 
$ ./exe -num 10 -v file.dat

Where:
"-num 10" set a particular variable/parameter to 10,
"-v" activated verbosity,
"file.dat" is some text file that will be read by the script.

I want the user to follow that order, so that he can NOT use the script in the following way:
 
$ ./exe -v file.dat -num 10



By now, I can write a script so that it taker either arguments OR parameters. I don't know how to get both.

Here is an example of what I can do now:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
g++ p.c -o exe
*/

#include <iostream>
#include <getopt.h>


// some global variable
bool verb = 0;
double ab = 0;

// print help on screen
void PrintHelp() {
	std::cout << " --verb :: \tVerbose output" << std::endl;
	std::cout << " --help :: \tShow help" << std::endl;
	return;
}

// process the parameters
void ProcessArgs(int argc, char** argv) {
	const char* const short_opts = "hv";
	const option long_opts[] = {
		{"verb",	no_argument,		nullptr,	'v'},
		{"help",	no_argument,		nullptr,	'h'},
		{nullptr,	no_argument,		nullptr,	0}
	};
	
	while (true) {
		const auto opt = getopt_long(argc, argv, short_opts, long_opts, nullptr);
		
		if (opt == -1) break;
		
		switch (opt) {
		case 'v':
			verb = 1;
			break;
		case 'h':
		case '?':
		default:
			PrintHelp();
			break;
		}
	}
}

int main (int argc, char** argv) {
	ProcessArgs(argc, argv);
	
	/* some magic should go here, so that if the user gives 'exe 12.2', then the variable ab is set to 12.2, but if he gives 'exe -v 12.2' than also verbosity is on */
	
	if (verb) {
		std::cout << "The value of variable AB is " << ab << std::endl;
	}
	
	return 0;
}



How can I change this example in order to pass both arguments and parameters to my script?

Thank you!
How can I change this example in order to pass both arguments and parameters to my script?
What is the difference between arguments and parameters?

You may take a look at the boost library:

https://www.boost.org/doc/libs/1_69_0/doc/html/program_options.html
Your terminology is non-standard. We usually call anything passed on the command line "command-line arguments". getopt and pals call command-line arguments that start with - (and are not exactly - or --) "option elements", and the character(s) after the - "option characters". Successive calls to getopt return successive option characters from the option elements or -1 when there are none left.

getopt_long and getopt_long_only also allow "long" versions of the options. getopt_long requires that long versions of options start with two dashes, e.g., --num. And the "arguments" to the long options are either passed after an attached equals sign or after a space, e.g., --num=42 or --num 42. getopt_long_only is like getopt_long except that you only need a single dash in front of long options. It should also be noted that both of these functions allow the long options to be abbreviated as long as the abbrev is unique.

If you really need the filename to be last then you can set "posixly-correct" mode by starting optstring with "+". Since you seem to want to use getopt_long_only (to be able to use a single dash in front of long options) and since the long options accept abbreviations you probably don't need anything but the "+" in optstring. Something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cstdlib>
#include <getopt.h>

int main(int argc, char **argv)
{
    using std::cout;

    bool verb = false;
    int num = 0;

    const char *opts = "+"; // set "posixly-correct" mode
    const option longopts[] {
        { "verbose", 0, 0, 'v' },
        { "num",     1, 0, 'n' },
        { 0,         0, 0, 0   }
    };

    for (int ch; (ch = getopt_long_only(argc, argv, opts, longopts, 0)) != -1; )
    {
        switch (ch)
        {
        case 'v':
            verb = true;
            break;
        case 'n':
            num = std::atoi(optarg);
            break;
        }
    }

    cout << (verb?"":"no ") << "verbose\n";
    cout << "num=" << num << '\n';

    if (argc - optind > 1)
        cout << "Extra argments\n";
    else if (optind == argc)
        cout << "Missing filename\n";
    else
        cout << "Filename: " << argv[optind] << '\n';
}

Last edited on
Topic archived. No new replies allowed.