Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Boost C++ Application Development  Cookbook

You're reading from   Boost C++ Application Development Cookbook Recipes to simplify your application development

Arrow left icon
Product type Paperback
Published in Aug 2017
Publisher Packt
ISBN-13 9781787282247
Length 438 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Anton Polukhin Alekseevic Anton Polukhin Alekseevic
Author Profile Icon Anton Polukhin Alekseevic
Anton Polukhin Alekseevic
Arrow right icon
View More author details
Toc

Table of Contents (13) Chapters Close

Preface 1. Starting to Write Your Application FREE CHAPTER 2. Managing Resources 3. Converting and Casting 4. Compile-Time Tricks 5. Multithreading 6. Manipulating Tasks 7. Manipulating Strings 8. Metaprogramming 9. Containers 10. Gathering Platform and Compiler Information 11. Working with the System 12. Scratching the Tip of the Iceberg

Getting configuration options

Take a look at some of the console programs, such as cp in Linux. They all have a fancy help; their input parameters do not depend on any position and have a human-readable syntax. For example:

$ cp --help
Usage: cp [OPTION]... [-T] SOURCE DEST
-a, --archive same as -dR --preserve=all
-b like --backup but does not accept an argument

You can implement the same functionality for your program in 10 minutes. All you need is the Boost.ProgramOptions library.

Getting ready

Basic knowledge of C++ is all you need for this recipe. Remember that this library is not only a header, so your program has to link against the libboost_program_options library.

How to do it...

Let's start with a simple program that accepts the count of apples and oranges as input and counts the total number of fruits. We want to achieve the following result:

 $ ./our_program.exe --apples=10 --oranges=20
Fruits count: 30

Perform the following steps:

  1. Include the boost/program_options.hpp header and make an alias for the boost::program_options namespace (it is too long to type it!). We would also need an <iostream> header:
#include <boost/program_options.hpp> 
#include <iostream>

namespace opt = boost::program_options;
  1. Now, we are ready to describe our options in the main() function:
int main(int argc, char *argv[])
{
// Constructing an options describing variable and giving
// it a textual description "All options".
opt::options_description desc("All options");

// When we are adding options, first parameter is a name
// to be used in command line. Second parameter is a type
// of that option, wrapped in value<> class. Third parameter
// must be a short description of that option.
desc.add_options()
("apples", opt::value<int>(), "how many apples do
you have")
("oranges", opt::value<int>(), "how many oranges do you
have")
("help", "produce help message")
;
  1. Let's parse the command line:
    // Variable to store our command line arguments.
opt::variables_map vm;

// Parsing and storing arguments.
opt::store(opt::parse_command_line(argc, argv, desc), vm);

// Must be called after all the parsing and storing.
opt::notify(vm);
  1. Let's add some code for processing the help option:
    if (vm.count("help")) {
std::cout << desc << "\n";
return 1;
}
  1. Final step. Counting fruits may be implemented in the following way:
    std::cout << "Fruits count: "
<< vm["apples"].as<int>() + vm["oranges"].as<int>()
<< std::endl;

} // end of `main`

Now, if we call our program with the help parameter, we'll get the following output:

All options: 
--apples arg how many apples do you have
--oranges arg how many oranges do you have
--help produce help message

As you can see, we do not provide a type for the help option's value, because we do not expect any values to be passed to it.

How it works...

This example is pretty simple to understand from code and comments. Running it produces the expected result:

 $ ./our_program.exe --apples=100 --oranges=20
Fruits count: 120

There's more...

The C++ standard adopted many Boost libraries; however, you won't find Boost.ProgramOptions even in C++17. Currently, there's no plan to adopt it into C++2a.

The ProgramOptions library is very powerful and has many features. Here's how to:

  • Parse configuration option values directly into a variable and make that option a required one:
    int oranges_var = 0;
desc.add_options()
// ProgramOptions stores the option value into
// the variable that is passed by pointer. Here value of
// "--oranges" option will be stored into 'oranges_var'.
("oranges,o", opt::value<int>(&oranges_var)->required(),
"oranges you have")
  • Get some mandatory string option:
        // 'name' option is not marked with 'required()',
// so user may not provide it.
("name", opt::value<std::string>(), "your name")
  • Add short name for apple, set 10 as a default value for apples:
        // 'a' is a short option name for apples. Use as '-a 10'.
// If no value provided, then the default value is used.
("apples,a", opt::value<int>()->default_value(10),
"apples that you have");
  • Get the missing options from the configuration file:
    opt::variables_map vm;

// Parsing command line options and storing values to 'vm'.
opt::store(opt::parse_command_line(argc, argv, desc), vm);

// We can also parse environment variables. Just use
// 'opt::store with' 'opt::parse_environment' function.

// Adding missing options from "apples_oranges.cfg" config file.
try {
opt::store(
opt::parse_config_file<char>("apples_oranges.cfg", desc),
vm
);
} catch (const opt::reading_file& e) {
std::cout << "Error: " << e.what() << std::endl;
}
The configuration file syntax differs from the command-line syntax. We do not need to place minuses before the options. So, our apples_oranges.cfg file must look like this:
oranges=20
  • Validate that all the required options were set:
    try {
// `opt::required_option` exception is thrown if
// one of the required options was not set.
opt::notify(vm);

} catch (const opt::required_option& e) {
std::cout << "Error: " << e.what() << std::endl;
return 2;
}

If we combine all the mentioned tips into a single executable, then its help command will produce this output:

$ ./our_program.exe --help
All options:
-o [ --oranges ] arg oranges that you have
--name arg your name
-a [ --apples ] arg (=10) apples that you have
--help produce help message

Running it without a configuration file will produce the following output:

$ ./our_program.exe
Error: can not read options configuration file 'apples_oranges.cfg'
Error: the option '--oranges' is required but missing

Running the program with oranges=20 in the configuration file will generate ++, because the default value for apples is 10:

$ ./our_program.exe
Fruits count: 30

See also

You have been reading a chapter from
Boost C++ Application Development Cookbook - Second Edition
Published in: Aug 2017
Publisher: Packt
ISBN-13: 9781787282247
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image