boost::program_options "polymorphic" argument - c++

I would like to use boost::program_options to create an executable which can be called as follows:
./example --nmax=0,10 # nmax is chosen randomly between 0 and 10
./example --nmax=9 # nmax is set to 9
./example # nmax is set to the default value of 10
What is the best way to achieve this, in a type-safe way, with minimum code?

I would like to use boost::program_options to create an executable
which can be called as follows:
the program_options library is very flexible, this can easily be supported by writing your own class with stream insertion and extraction operators.
#include <iostream>
#include <limits>
#include <stdlib.h>
#include <boost/lexical_cast.hpp>
#include <boost/program_options.hpp>
class Max
{
public:
Max() :
_max( std::numeric_limits<int>::max() )
{
}
Max(
int max
) :
_max( max )
{
}
Max(
int low,
int high
)
{
int value = rand();
value %= (high - low);
value += low;
_max = value;
}
int value() const { return _max; }
private:
int _max;
};
std::ostream&
operator<<(
std::ostream& os,
const Max& foo
)
{
os << foo.value();
return os;
}
std::istream&
operator>>(
std::istream& is,
Max& foo
)
{
std::string line;
std::getline( is, line );
if ( !is ) return is;
const std::string::size_type comma = line.find_first_of( ',' );
try {
if ( comma != std::string::npos ) {
const int low = boost::lexical_cast<int>( line.substr(0, comma) );
const int high = boost::lexical_cast<int>( line.substr(comma + 1) );
foo = Max( low, high );
} else {
foo = Max( boost::lexical_cast<int>(line) );
}
} catch ( const boost::bad_lexical_cast& e ) {
std::cerr << "garbage when convering Max value '" << line << "'" << std::endl;
is.setstate( std::ios::failbit );
}
return is;
}
int
main( int argc, char** argv )
{
namespace po = boost::program_options;
Max nmax;
po::options_description options;
options.add_options()
("nmax", po::value(&nmax)->default_value(10), "random number range, or value" )
("help,h", po::bool_switch(), "help text")
;
po::variables_map vm;
try {
po::command_line_parser cmd_line( argc, argv );
cmd_line.options( options );
po::store( cmd_line.run(), vm );
po::notify( vm );
} catch ( const boost::program_options::error& e ) {
std::cerr << e.what() << std::endl;
exit( EXIT_FAILURE );
}
if ( vm["help"].as<bool>() ) {
std::cout << argv[0] << " [OPTIONS]" << std::endl;
std::cout << std::endl;
std::cout << "OPTIONS:" << std::endl;
std::cout << options << std::endl;
exit(EXIT_SUCCESS);
}
std::cout << "random value: " << nmax.value() << std::endl;
}
sample session
samm:stackoverflow samm$ ./a.out
random value: 10
samm:stackoverflow samm$ ./a.out --nmax 55
random value: 55
samm:stackoverflow samm$ ./a.out --nmax 10,25
random value: 17
samm:stackoverflow samm$

The library doesn't offer "polymorphic" argument types like you suggest. Each argument has exactly one type. If you want to make it have different values based on the syntax of the argument, you need to add that functionality yourself.
The easy way is to do as Kerrek's comment suggests and use a string, and then parse it afterward. It doesn't really take much code.
Another way is to use a custom validator. Make up a special type dedicated to this format of argument, and then write a validate function that converts string values into values of your custom type. Throw an exception if validation fails; the Program_Options library will treat it just like a validation failure of any of the built-in types. I wrote an example validator in response to another question.
The code you'll write for this is pretty much the same code you'd write to parse the string after parsing the command line; it's just a matter of whether you build it into the argument type, or just process it afterward.

I am posting this code here, hoping it will prove useful to somebody. It is the "templatized" version of Sam Miller's answer.
#ifndef RANDOMCONSTANT_HH
#define RANDOMCONSTANT_HH
#include <boost/random.hpp>
boost::random::mt19937 g_randomConstantPrng(static_cast<unsigned int>(std::time(NULL) + getpid()));
template<typename T>
class RandomConstant
{
public:
RandomConstant() { /* nothing */ }
RandomConstant(T value) : _value(value) { /* nothing */ }
RandomConstant(int low, int high)
{
boost::random::uniform_int_distribution<> dist(low, high);
_value = dist(g_randomConstantPrng);
}
RandomConstant(double low, double high)
{
boost::random::uniform_real_distribution<> dist(low, high);
_value = dist(g_randomConstantPrng);
}
T value() const { return _value; }
private:
T _value;
};
template<typename T>
std::ostream&
operator<<(std::ostream& os, const RandomConstant<T>& foo)
{
os << foo.value();
return os;
}
template<typename T>
std::istream&
operator>>(std::istream &is, RandomConstant<T> &foo)
{
std::string line;
std::getline(is, line);
if (!is) return is;
const std::string::size_type comma = line.find_first_of( ',' );
if (comma != std::string::npos)
{
const T low = boost::lexical_cast<T>( line.substr(0, comma) );
const T high = boost::lexical_cast<T>( line.substr(comma + 1) );
foo = RandomConstant<T>(low, high);
}
else
{
foo = RandomConstant<T>(boost::lexical_cast<T>(line));
}
return is;
}
#endif /* RANDOMCONSTANT_HH */
Used as follows:
namespace po = boost::program_options;
po::options_description desc;
desc.add_options()
("help", "show help")
("intValue", po::value<RandomConstant<int>>()->default_value(3), "description 1")
("doubleValue", po::value<RandomConstant<double>>()->default_value(1.5), "description 2")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help")) {
std::cerr << desc << std::endl;
return EXIT_FAILURE;
}
int intValue = vm["intValue"].as<RandomConstant<int>>().value();
double doubleValue = vm["doubleValue"].as<RandomConstant<double>>().value();

You can probably use multitoken
po::options_description desc("Allowed options");
desc.add_options()
("nmax", po::value< std::vector< float > >()->multitoken()->default_value(10), "description")
;
...
float value;
if (vm.count["nmax"] == 2)
value = random value ...
else
value = vm["nmax"].as< std::vector< float > >()[0];

Related

Why is count_if giving me the total of texts

I was testing the following code, and a bit perplexed as to why count_if is returning me the total of texts?
Match function that takes string of Text as argument and returns true is the Text size is 4
bool Match(string Text)
{
if (Text.size() == 4)
return true;
}
numMatchwes produces the total number of Text in a vector
int numMatches(vector<string>Texts, bool (*Match)(string Text)) // Texts is an array
{
int count = 0;
for (int i = 0; i < Texts.size(); i++)
{
if (Match(Texts[i]) == 1)
// checking every string in vector and returns true
count++;
}
return count;
}
The main function
int main()
{
vector<string> texts;
texts.push_back("Bing");
texts.push_back("Pony");
texts.push_back("Mil");
texts.push_back("Sillty");
texts.push_back("Ballz");
texts.push_back("Mars");
cout << Match("Sind") << endl;
cout << "Matches are: " << numMatches(texts, Match) << endl;
cout << endl;
int num = count_if(texts.begin(), texts.end(), Match); // count_if is STL function
cout << num << endl;
}
Now I’m confused as to why count_if is giving me the total of texts?
The function Match has undefined behavior in case when the passed string does not have a length equal to 4.
Define it the following way
bool Match( const std::string &Text )
{
return Text.size() == 4;
}
Correspondingly the function numMatches can be defined the following way
auto numMatches( const std::vector<std::string> &Texts, bool Match(const std::string & ) )
{
std::vector<std::string>::size_type count = 0;
for ( const auto &s : Texts )
{
if ( Match( s ) ) ++count;
}
return count;
}
Here is your updated program.
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
auto numMatches( const std::vector<std::string> &Texts, bool Match(const std::string & ) )
{
std::vector<std::string>::size_type count = 0;
for ( const auto &s : Texts )
{
if ( Match( s ) ) ++count;
}
return count;
}
bool Match( const std::string &Text )
{
return Text.size() == 4;
}
int main()
{
std::vector<std::string> texts;
texts.push_back( "Bing" );
texts.push_back( "Pony" );
texts.push_back( "Mil" );
texts.push_back( "Sillty" );
texts.push_back( "Ballz" );
texts.push_back( "Mars" );
std::cout << std::boolalpha << Match( "Sind" ) << '\n';
std::cout << "Matches are: " << numMatches( texts, Match ) << '\n';
std::cout << '\n';
auto num = std::count_if( std::begin( texts ), std::end( texts ), Match );
std::cout << num << std::endl;
return 0;
}
The program output is
true
Matches are: 3
3

Problem with std::sort function. Seem to always have null value for 1 element after 2 rounds of iteraion

I am trying to write a sort program trying to sort a data set I have. The key to the sorting is Grid_ID and it happened to be an alpha-numeric data. I have tried to sort accordingly
It give me an error
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::at: __n (which is 0) >= this->size() (which is
0)
On doing debugging, the reading part of the code seems to function. The reading of file content into DataContainer data get filled with the right data of key and text position.
But when it come to std::sort, when the program "less" is invoked, const GridLabel& elem2 always turn up to be zero or null after 2nd iteration
Below is some data set and partial source code (I do not include the write the content in sorted order here but should be runnable)
THanks for help!
This is the partial data set
Grid_Id,Speed,Acc,ID
K31,173,8.37,1
K29,143,3.36,2
K29,107,4.56,3
K30,133,5.97,4
K30,153,2.38,5
J27,203,1.86,6
J27,143,1.59,7
I26,73,7.66,8
I27,134,2.86,9
This is the code
#include <algorithm>
#include <functional>
#include <fstream>
#include <string>
#include <deque>
#include <vector>
#include <iostream>
#include <sstream>
struct GridLabel
{
std::string key_;
std::istream::pos_type pos_; // position in stream where this line starts
GridLabel( const std::string& key, const std::istream::pos_type& pos) : key_( key)
, pos_( pos)
{
}
const GridLabel& operator=( const GridLabel& other)
{
key_ = other.key_;
pos_ = other.pos_;
return *this;
}
};
typedef std::vector< GridLabel> DataContainer;
// Return whether first element is smaller than the second
bool less( const GridLabel& elem1, const GridLabel& elem2 )
{
std::stringstream ss1, ss2;
ss1 << elem1.key_.at(0);
ss2 << elem2.key_.at(0);
int value = (ss1.str()).compare(ss2.str());
if( value < 0 )
{
return true;
}
else if( value == 0)
{
// need to check if the rest are smaller
std::string substr1 = elem1.key_.substr(1, std::string::npos);
std::string substr2 = elem2.key_.substr(1, std::string::npos);
return (std::atoi(substr1.c_str()) < std::atoi(substr2.c_str()));
}
else
{
return false;
}
}
int main(int argc, char* argv[])
{
DataContainer data;
// read data into the vector here
std::ifstream input( "some_file.csv");
// check if it is correct
if ( !input.good())
{
std::cerr << "Input file can not be openned." << std::endl;
return -1;
}
std::string text;
std::string key;
std::istream::pos_type pos;
int count=0, save=0;
// to skip the header
std::getline( input, text);
for( int line = 0; !input.eof(); ++line)
{
// store the position before reading the line
pos = input.tellg();
std::getline( input, text);
// parse it
save = text.find(",");
key = text.substr(0,(save));
data.push_back( GridLabel( key, pos));
}
// sort the data in sorted order
std::sort( data.begin(), data.end(), less);
// create the new file
...............
return 0;
}
A simplified less() to compare
the first characters of GridLabel::key
the integral number starting from 2nd character of GridLabel::key.
This will not consider what else is stored in GridLabel::key. (This might be intended by OP.)
Sample:
#include <algorithm>
#include <iostream>
#include <string>
struct GridLabel {
std::string key;
};
bool less(const GridLabel &elem1, const GridLabel &elem2)
{
// compare first chars of keys
const char c1 = elem1.key.at(0), c2 = elem2.key.at(0);
if (c1 != c2) return c1 < c2;
// compare integral beginning in 2nd char of keys
const int i1 = atoi(elem1.key.c_str() + 1);
const int i2 = atoi(elem2.key.c_str() + 1);
return i1 < i2;
}
int main()
{
GridLabel data[] = {
{ "K31,173,8.37,1" },
{ "K29,143,3.36,2" },
{ "K29,107,4.56,3" },
{ "K30,133,5.97,4" },
{ "K30,153,2.38,5" },
{ "J27,203,1.86,6" },
{ "J27,143,1.59,7" },
{ "I26,73,7.66,8" },
{ "I27,134,2.86,9" }
};
{ std::cout << "Original data:\n";
int i = 0;
for (const GridLabel &entry : data) {
std::cout << i++ << ": '" << entry.key << "'\n";
}
}
std::cout << "Sorting...";
std::sort(std::begin(data), std::end(data), less);
std::cout << " Done.\n";
{ std::cout << "Sorted data:\n";
int i = 0;
for (const GridLabel &entry : data) {
std::cout << i++ << ": '" << entry.key << "'\n";
}
}
}
Output:
Original data:
0: 'K31,173,8.37,1'
1: 'K29,143,3.36,2'
2: 'K29,107,4.56,3'
3: 'K30,133,5.97,4'
4: 'K30,153,2.38,5'
5: 'J27,203,1.86,6'
6: 'J27,143,1.59,7'
7: 'I26,73,7.66,8'
8: 'I27,134,2.86,9'
Sorting... Done.
Sorted data:
0: 'I26,73,7.66,8'
1: 'I27,134,2.86,9'
2: 'J27,203,1.86,6'
3: 'J27,143,1.59,7'
4: 'K29,143,3.36,2'
5: 'K29,107,4.56,3'
6: 'K30,133,5.97,4'
7: 'K30,153,2.38,5'
8: 'K31,173,8.37,1'
Live Demo on coliru
Please, note that (according to how predicate less() is implemented) there are a lot elements which are considered as equal:
I26,73,7.66,8 with I27,134,2.86,9
J27,203,1.86,6 with J27,143,1.59,7
etc.
These elements will appear in abitrary order after sorting.
Alternatively, std::stable_sort() could be used which will preserve the original order in these cases.

Read/Write inifiles with boost::{program_options,property_tree}

Utilizing boost, I would like to
read options from an inifile, abort if an unknown option is encountered in the inifile and
save them later in another inifile.
The first part can be done with boost::program_options:
try{
inifile_options.add_options()
("ops1.i0", po::value<int>(&p.nx)->default_value(1), "test integer")
;
po::variables_map vm;
po::store(po::parse_config_file(pthfnini, inifile_options), vm);
po::notify(vm);
}
catch(exception& e){
cerr << "error: " << e.what() << "\n";
errorflag=1;
}
To the best of my knowledge writing an inifile is not possible with boost::program_options, but boost::property_tree works:
pt::ptree iniPropTree;
pt::ini_parser::write_ini("./used0.ini",iniPropTree);
Now the question is how can I translate the data stored in the po::variables_map to pt::ptree?
Reading the boost documentation leaves me with the impression that this is not possible. Is the following the only viable way?
iniPropTree.put<int>("ops1.i0",vm["ops1.i0"].as<int>();
It introduces quite a bit of redundancy for my taste. However, reading data into a property tree from the beginning does not seem to support checking for undefined/misspelled options.
Alternatively,is it possible to iterate over the contents of variables_map and somehow infer the corresponding datatype of each element?
The full code is here:
/*
* g++ iniOps_test.cpp -Wall -std=c++11 -O3 -lboost_system -lboost_program_options -o iniOps_test.exe
*
*/
// C++11 & Boost libraries
#include <boost/program_options.hpp> // po::options_description, po::variables_map, ...
#include <boost/property_tree/ptree.hpp> // pt::ptree
#include <boost/property_tree/ini_parser.hpp> // write_ini()
#include <iostream> // cout
#include <fstream> // ofstream, ifstream
// namespaces
namespace po = boost::program_options;
namespace pt = boost::property_tree;
using namespace std;
struct params{
std::string inipthfn;
int i0;
};
void read_inifile(params &p, po::variables_map &vm){
// initialize variables
int errorflag=0;
std::ifstream pthfnini("./testini.ini");
po::options_description inifile_options("Allowed inifile options");
try{
inifile_options.add_options()
("ops1.i0", po::value<int>(&p.i0)->default_value(1), "test integer")
;
;
po::store(po::parse_config_file(pthfnini, inifile_options), vm);
po::notify(vm);
}
catch(exception& e){
cerr << "error: " << e.what() << "\n";
errorflag=1;
}
pthfnini.close();
if(errorflag){ std::cout<<"--- program shutdown due to error in read_inifile ---"<<std::endl; exit(1); }
}
int main(){
params p;
po::variables_map vm;
pt::ptree iniPropTree;
read_inifile(p,vm); // get options from inifile
// ??? conversion from vm -> pt ???
pt::ini_parser::write_ini("./used0.ini",iniPropTree); // save options to used.ini
cout << p.i0 << endl;
return 0;
}
The contents of the inifile "testini.ini" are:
[ops1]
i0=2
There's a conceptual problem here.
Commandline parameters are inherently textual.
Values in the variables-map aren't. The types used are configured in the value-semantics (part of your options-description).
If all your options have the same type, you can "cheat" and hard-code a conversion:
pt::ptree to_ptree(po::variables_map const& vm) {
pt::ptree tree;
for (auto& v : vm) {
if (!v.second.empty() && !v.second.defaulted())
tree.put(v.first, v.second.as<int>());
}
return tree;
}
Which saves:
[ops1]
i0=1
If you need more flexibility, you'd need access to the option descriptions at the very least. This is not the intended use of the library, and you'll probably run into undocumented parts of the implementation soon.
However, reading data into a property tree from the beginning does not seem to support checking for undefined/misspelled options
Well. That's not entirely true. You can make your own parse function that adds the logic. Use Property Tree Translators if you want.
Here's an extended example showing three parameters of varying types to be validated:
enum class restricted { value1, value2 };
struct params {
int i0 = 1;
restricted r1 = restricted::value2;
std::string s2 = "some default";
};
We will want to have a parse function like this:
params read_inifile(std::string filename) {
params p;
pt::ptree tree;
std::ifstream file(filename);
read_ini(file, tree);
p.i0 = tree.get("ops1.i0", 1);
p.r1 = tree.get("ops1.r1", restricted::value2);
p.s2 = tree.get("ops1.s2", "some default");
return p;
}
Streamable Types
To translate and validate the enum you merely need to implement the streaming operators:
static inline std::istream& operator>>(std::istream& is, restricted& r) {
std::string v;
if (is >> std::ws >> v) {
if (boost::iequals("value1", v))
r = restricted::value1;
else if (boost::iequals("value2", v))
r = restricted::value2;
else
throw std::runtime_error("invalid restricted value");
}
return is;
}
static inline std::ostream& operator<<(std::ostream& os, restricted r) {
switch(r) {
case restricted::value1: return os << "value1";
case restricted::value2: return os << "value2";
default: return os << "invalid";
}
}
Custom Translators
Let's imagine that i0 need custom validation. In this example, let's REQUIRE it to be an odd number:
namespace translators {
template <typename T>
struct must_be_odd {
typedef T internal_type;
typedef T external_type;
boost::optional<T> get_value(const std::string& str) const {
if (str.empty()) return boost::none;
T v = boost::lexical_cast<T>(str);
if (v % 2 == 0)
throw std::runtime_error("value must be odd");
return boost::make_optional(v);
}
boost::optional<std::string> put_value(const T& i0) {
assert(i0 % 2); // assert that the value was odd
return boost::lexical_cast<std::string>(i0);
}
};
static const must_be_odd<int> i0;
}
Now we can simply supply the translator (here, acting more like a custom validator like Boost Program Options also has them):
p.i0 = tree.get("ops1.i0", 1, translators::i0);
See it Live On Coliru
Unsupported Options
This is a bit more work. You'll have to iterate the tree checking the resultant paths against a known set. Here's a stab at a reasonably generic implementation of that (which should work correctly with case sensitive trees of any (wide) string type):
template <typename Tree,
typename Path = typename Tree::path_type,
typename Key = typename Path::key_type,
typename Cmp = typename Tree::key_compare>
std::size_t unsupported(Tree const& tree, std::set<Key, Cmp> const& supported, Path prefix = "") {
if (tree.size()) {
std::size_t n = 0;
for (auto& node : tree) {
Path sub = prefix;
sub /= node.first;
n += unsupported(node.second, supported, sub);
}
return n;
} else {
if (!supported.count(prefix.dump()) && tree.template get_value_optional<std::string>())
return 1;
}
return 0;
}
You can use it like this:
if (auto n = unsupported(tree, {"ops1.i0", "ops1.r1", "ops2.s2"})) {
throw std::runtime_error(std::to_string(n) + " unsupported options");
}
Full Demo
Live On Coliru
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <set>
enum class restricted { value1, value2 };
static inline std::istream& operator>>(std::istream& is, restricted& r) {
std::string v;
if (is >> std::ws >> v) {
if (boost::iequals("value1", v))
r = restricted::value1;
else if (boost::iequals("value2", v))
r = restricted::value2;
else
throw std::runtime_error("invalid restricted value");
}
return is;
}
static inline std::ostream& operator<<(std::ostream& os, restricted r) {
switch(r) {
case restricted::value1: return os << "value1";
case restricted::value2: return os << "value2";
default: return os << "invalid";
}
}
struct params {
int i0 = 1;
restricted r1 = restricted::value2;
std::string s2 = "some default";
};
#include <boost/property_tree/ini_parser.hpp>
#include <boost/lexical_cast.hpp>
#include <fstream>
namespace pt = boost::property_tree;
namespace translators {
template <typename T>
struct must_be_odd {
typedef T internal_type;
typedef T external_type;
boost::optional<T> get_value(const std::string& str) const {
if (str.empty()) return boost::none;
T v = boost::lexical_cast<T>(str);
if (v % 2 == 0)
throw std::runtime_error("value must be odd");
return boost::make_optional(v);
}
boost::optional<std::string> put_value(const T& i0) {
assert(i0 % 2); // assert that the value was odd
return boost::lexical_cast<std::string>(i0);
}
};
static const must_be_odd<int> i0;
}
template <typename Tree,
typename Path = typename Tree::path_type,
typename Key = typename Path::key_type,
typename Cmp = typename Tree::key_compare>
std::size_t unsupported(Tree const& tree, std::set<Key, Cmp> const& supported, Path prefix = "") {
if (tree.size()) {
std::size_t n = 0;
for (auto& node : tree) {
Path sub = prefix;
sub /= node.first;
n += unsupported(node.second, supported, sub);
}
return n;
} else {
if (!supported.count(prefix.dump()) && tree.template get_value_optional<std::string>())
return 1;
}
return 0;
}
params read_inifile(std::string filename) {
params p;
try {
pt::ptree tree;
std::ifstream file(filename);
read_ini(file, tree);
p.i0 = tree.get("ops1.i0", 1, translators::i0);
p.r1 = tree.get("ops1.r1", restricted::value2);
p.s2 = tree.get("ops1.s2", "some default");
if (auto n = unsupported(tree, {"ops1.i0", "ops1.r1", "ops2.s2"})) {
throw std::runtime_error(std::to_string(n) + " unsupported options");
}
} catch (std::exception const& e) {
std::cerr << "error: " << e.what() << "\n";
throw std::runtime_error("read_inifile");
}
return p;
}
pt::ptree to_ptree(params const& p) {
pt::ptree tree;
tree.put("ops1.i0", p.i0, translators::i0);
tree.put("ops1.r1", p.r1);
tree.put("ops1.s2", p.s2);
return tree;
}
int main() {
params const p = read_inifile("./testini.ini"); // get options from filename
write_ini("./used0.ini", to_ptree(p)); // save options to used.ini
std::cout << p.i0 << std::endl;
}
For input like
[ops1]
i0=17
i99=oops
[oops1]
also=oops
Prints
error: 2 unsupported options
terminate called after throwing an instance of 'std::runtime_error'
what(): read_inifile
And changing 17 to 18 prints:
error: value must be odd
terminate called after throwing an instance of 'std::runtime_error'
what(): read_inifile
On valid input, used0.ini will be written as expected:
[ops1]
i0=1
r1=value2
s2=some default
After giving this problem some more time, I found a suitable compact solution:
The key is to write a function that translates entries from the variables_map to the propTree depending on their datatype (thx to sehe for putting me on the right track):
void translate_variables_map_to_ptree(po::variables_map &vm, pt::ptree &propTree){
for(po::variables_map::iterator it=vm.begin(); it!=vm.end(); it++){
if( it->second.value().type() == typeid(int) ){ propTree.put<int>(it->first,vm[it->first].as<int>()); }
else if( it->second.value().type() == typeid(float) ){ propTree.put<float>(it->first,vm[it->first].as<float>()); }
else if( it->second.value().type() == typeid(double) ){ propTree.put<double>(it->first,vm[it->first].as<double>()); }
else if( it->second.value().type() == typeid(std::string) ){ propTree.put<std::string>(it->first,vm[it->first].as<std::string>()); }
else if( it->second.value().type() == typeid(size_t) ){ propTree.put<size_t>(it->first,vm[it->first].as<size_t>()); }
else{ printf("Error: unknown datatype. Abort!\n"); exit(EXIT_FAILURE); }
}
}
The full working example writes the correct inifile containing all read info:
/*
* g++ iniOps_test.cpp -Wall -std=c++11 -O3 -lboost_system -lboost_program_options -o iniOps_test.exe
*
*/
// C++11 & Boost libraries
#include <boost/program_options.hpp> // po::options_description, po::variables_map, ...
#include <boost/property_tree/ptree.hpp> // pt::ptree
#include <boost/property_tree/ini_parser.hpp> // write_ini()
#include <iostream> // cout
#include <fstream> // ofstream, ifstream
// namespaces
namespace po = boost::program_options;
namespace pt = boost::property_tree;
using namespace std;
struct params{
std::string s0;
int i0;
};
void read_inifile(params &p, po::variables_map &vm){
// initialize variables
int errorflag=0;
std::ifstream pthfnini("./testini.ini");
po::options_description inifile_options("Allowed inifile options");
try{
inifile_options.add_options()
("ops1.i0", po::value<int>(&p.i0)->default_value(1), "test integer")
("ops1.s0", po::value<std::string>(&p.s0)->default_value("default"), "test string")
;
;
po::store(po::parse_config_file(pthfnini, inifile_options), vm);
po::notify(vm);
}
catch(exception& e){
cerr << "error: " << e.what() << "\n";
errorflag=1;
}
pthfnini.close();
if(errorflag){ std::cout<<"--- program shutdown due to error in read_inifile ---"<<std::endl; exit(1); }
}
void translate_variables_map_to_ptree(po::variables_map &vm, pt::ptree &propTree){
for(po::variables_map::iterator it=vm.begin(); it!=vm.end(); it++){
if( it->second.value().type() == typeid(int) ){ propTree.put<int>(it->first,vm[it->first].as<int>()); }
else if( it->second.value().type() == typeid(float) ){ propTree.put<float>(it->first,vm[it->first].as<float>()); }
else if( it->second.value().type() == typeid(double) ){ propTree.put<double>(it->first,vm[it->first].as<double>()); }
else if( it->second.value().type() == typeid(std::string) ){ propTree.put<std::string>(it->first,vm[it->first].as<std::string>()); }
else if( it->second.value().type() == typeid(size_t) ){ propTree.put<size_t>(it->first,vm[it->first].as<size_t>()); }
else{ printf("Error: unknown datatype. Abort!\n"); exit(EXIT_FAILURE); }
}
}
int main(){
params p;
po::variables_map vm;
pt::ptree iniPropTree;
read_inifile(p,vm); // get options from inifile
translate_variables_map_to_ptree(vm,iniPropTree); // conversion from vm -> pt
pt::ini_parser::write_ini("./used0.ini",iniPropTree); // save options to used.ini
cout << p.i0 << endl;
cout << p.s0 << endl;
return 0;
}
Taking a variables_map vm from reading the commandline, it is also possible to update the values in the property tree (from reading the inifile) with:
string opsName = "ops1.i0"; if(vm.count(opsName)) p.i0 = vm[opsName].as<int>();

Storing vector of doubles into a text file [duplicate]

How do I do the following with std::cout?
double my_double = 42.0;
char str[12];
printf_s("%11.6lf", my_double); // Prints " 42.000000"
I am just about ready to give up and use sprintf_s.
More generally, where can I find a reference on std::ostream formatting that lists everything in one place, rather than spreading it all out in a long tutorial?
EDIT Dec 21, 2017 - See my answer below. It uses features that were not available when I asked this question in 2012.
std::cout << std::fixed << std::setw(11) << std::setprecision(6) << my_double;
You need to add
#include <iomanip>
You need stream manipulators
You may "fill" the empty places with whatever char you want. Like this:
std::cout << std::fixed << std::setw(11) << std::setprecision(6)
<< std::setfill('0') << my_double;
std::cout << boost::format("%11.6f") % my_double;
You have to #include <boost\format.hpp>
In C++20 you can to do
double my_double = 42.0;
char str[12];
std::format_to_n(str, sizeof(str), "{:11.6}", my_double);
or
std::string s = std::format("{:11.6}", my_double);
In pre-C++20 you can use the {fmt} library that provides an implementation of format_to_n.
Disclaimer: I'm the author of {fmt} and C++20 std::format.
In general, you want to avoid specifying things like 11 and 6 at the
point of output. That's physical markup, and you want logical markup;
e.g. pressure, or volume. That way, you define in a single place
how pressure or volume are formatted, and if that formatting changes,
you don't have to search through out the program to find where to change
the format (and accidentally change the format of something else). In
C++, you do this by defining a manipulator, which sets the various
formatting options, and preferrably restores them at the end of the full
expression. So you end up writing things like:
std::cout << pressure << my_double;
Although I definitly wouldn't use it in production code, I've found the
following FFmt formatter useful for quicky jobs:
class FFmt : public StateSavingManip
{
public:
explicit FFmt(
int width,
int prec = 6,
std::ios::fmtflags additionalFlags
= static_cast<std::ios::fmtflags>(),
char fill = ' ' );
protected:
virtual void setState( std::ios& targetStream ) const;
private:
int myWidth;
int myPrec;
std::ios::fmtflags myFlags;
char myFill;
};
FFmt::FFmt(
int width,
int prec,
std::ios::fmtflags additionalFlags,
char fill )
: myWidth( width )
, myPrec( prec )
, myFlags( additionalFlags )
, myFill( fill )
{
myFlags &= ~ std::ios::floatfield
myFlags |= std::ios::fixed
if ( isdigit( static_cast< unsigned char >( fill ) )
&& (myFlags & std::ios::adjustfield) == 0 ) {
myFlags |= std::ios::internal
}
}
void
FFmt::setState(
std::ios& targetStream ) const
{
targetStream.flags( myFlags )
targetStream.width( myWidth )
targetStream.precision( myPrec )
targetStream.fill( myFill )
}
This allows writing things like:
std::cout << FFmt( 11, 6 ) << my_double;
And for the record:
class StateSavingManip
{
public:
StateSavingManip(
StateSavingManip const& other );
virtual ~StateSavingManip();
void operator()( std::ios& stream ) const;
protected:
StateSavingManip();
private:
virtual void setState( std::ios& stream ) const = 0;
private:
StateSavingManip& operator=( StateSavingManip const& );
private:
mutable std::ios* myStream;
mutable std::ios::fmtflags
mySavedFlags;
mutable int mySavedPrec;
mutable char mySavedFill;
};
inline std::ostream&
operator<<(
std::ostream& out,
StateSavingManip const&
manip )
{
manip( out );
return out;
}
inline std::istream&
operator>>(
std::istream& in,
StateSavingManip const&
manip )
{
manip( in );
return in;
}
StateSavingManip.cc:
namespace {
// We maintain the value returned by ios::xalloc() + 1, and not
// the value itself. The actual value may be zero, and we need
// to be able to distinguish it from the 0 resulting from 0
// initialization. The function getXAlloc() returns this value
// -1, so we add one in the initialization.
int getXAlloc();
int ourXAlloc = getXAlloc() + 1;
int
getXAlloc()
{
if ( ourXAlloc == 0 ) {
ourXAlloc = std::ios::xalloc() + 1;
assert( ourXAlloc != 0 );
}
return ourXAlloc - 1;
}
}
StateSavingManip::StateSavingManip()
: myStream( NULL )
{
}
StateSavingManip::StateSavingManip(
StateSavingManip const&
other )
{
assert( other.myStream == NULL );
}
StateSavingManip::~StateSavingManip()
{
if ( myStream != NULL ) {
myStream->flags( mySavedFlags );
myStream->precision( mySavedPrec );
myStream->fill( mySavedFill );
myStream->pword( getXAlloc() ) = NULL;
}
}
void
StateSavingManip::operator()(
std::ios& stream ) const
{
void*& backptr = stream.pword( getXAlloc() );
if ( backptr == NULL ) {
backptr = const_cast< StateSavingManip* >( this );
myStream = &stream;
mySavedFlags = stream.flags();
mySavedPrec = stream.precision();
mySavedFill = stream.fill();
}
setState( stream );
}
#include <iostream>
#include <iomanip>
int main() {
double my_double = 42.0;
std::cout << std::fixed << std::setw(11)
<< std::setprecision(6) << my_double << std::endl;
return 0;
}
For future visitors who prefer actual printf-style format specs with std::ostream, here is yet another variation, based on Martin York's excellent post in another SO question: https://stackoverflow.com/a/535636:
#include <iostream>
#include <iomanip>
#include <stdio.h> //snprintf
class FMT
{
public:
explicit FMT(const char* fmt): m_fmt(fmt) {}
private:
class fmter //actual worker class
{
public:
explicit fmter(std::ostream& strm, const FMT& fmt): m_strm(strm), m_fmt(fmt.m_fmt) {}
//output next object (any type) to stream:
template<typename TYPE>
std::ostream& operator<<(const TYPE& value)
{
// return m_strm << "FMT(" << m_fmt << "," << value << ")";
char buf[40]; //enlarge as needed
snprintf(buf, sizeof(buf), m_fmt, value);
return m_strm << buf;
}
private:
std::ostream& m_strm;
const char* m_fmt;
};
const char* m_fmt; //save fmt string for inner class
//kludge: return derived stream to allow operator overloading:
friend FMT::fmter operator<<(std::ostream& strm, const FMT& fmt)
{
return FMT::fmter(strm, fmt);
}
};
usage example:
double my_double = 42.0;
cout << FMT("%11.6f") << my_double << "more stuff\n";
or even:
int val = 42;
cout << val << " in hex is " << FMT(" 0x%x") << val << "\n";
it's me, the OP, Jive Dadson - five years on. C++17 is becoming a reality.
The advent of variadic template parameters with perfect forwarding has made life so much simpler. The chained madness of ostream<< and boost::format% can be dispensed with. The function oprintf below fills the bill. Work in progress. Feel free to chime in on error-handling, etc...
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <string_view>
namespace dj {
template<class Out, class... Args>
Out& oprintf(Out &out, const std::string_view &fmt, Args&&... args) {
const int sz = 512;
char buffer[sz];
int cx = snprintf(buffer, sz, fmt.data(), std::forward<Args>(args)...);
if (cx >= 0 && cx < sz) {
return out.write(buffer, cx);
} else if (cx > 0) {
// Big output
std::string buff2;
buff2.resize(cx + 1);
snprintf(buff2.data(), cx, fmt.data(), std::forward<Args>(args)...);
return out.write(buff2.data(), cx);
} else {
// Throw?
return out;
}
}
}
int main() {
const double my_double = 42.0;
dj::oprintf(std::cout, "%s %11.6lf\n", "My double ", my_double);
return 0;
}
Some great answers already; kudos to those!
This is based on some of them. I have added type assertions for POD types, since they are the only safe types usable with printf().
#include <iostream>
#include <stdio.h>
#include <type_traits>
namespace fmt {
namespace detail {
template<typename T>
struct printf_impl
{
const char* fmt;
const T v;
printf_impl(const char* fmt, const T& v) : fmt(fmt), v(v) {}
};
template<typename T>
inline typename std::enable_if<std::is_pod<T>::value, std::ostream& >::type
operator<<(std::ostream& os, const printf_impl<T>& p)
{
char buf[40];
::snprintf(buf, sizeof(buf), p.fmt, p.v, 40);
return os << buf;
}
} // namespace detail
template<typename T>
inline typename std::enable_if<std::is_pod<T>::value, detail::printf_impl<T> >::type
printf(const char* fmt, const T& v)
{
return detail::printf_impl<T>(fmt, v);
}
} // namespace fmt
Example usage it as below.
std::cout << fmt::printf("%11.6f", my_double);
Give it a try on Coliru.

Floating point format for std::ostream

How do I do the following with std::cout?
double my_double = 42.0;
char str[12];
printf_s("%11.6lf", my_double); // Prints " 42.000000"
I am just about ready to give up and use sprintf_s.
More generally, where can I find a reference on std::ostream formatting that lists everything in one place, rather than spreading it all out in a long tutorial?
EDIT Dec 21, 2017 - See my answer below. It uses features that were not available when I asked this question in 2012.
std::cout << std::fixed << std::setw(11) << std::setprecision(6) << my_double;
You need to add
#include <iomanip>
You need stream manipulators
You may "fill" the empty places with whatever char you want. Like this:
std::cout << std::fixed << std::setw(11) << std::setprecision(6)
<< std::setfill('0') << my_double;
std::cout << boost::format("%11.6f") % my_double;
You have to #include <boost\format.hpp>
In C++20 you can to do
double my_double = 42.0;
char str[12];
std::format_to_n(str, sizeof(str), "{:11.6}", my_double);
or
std::string s = std::format("{:11.6}", my_double);
In pre-C++20 you can use the {fmt} library that provides an implementation of format_to_n.
Disclaimer: I'm the author of {fmt} and C++20 std::format.
In general, you want to avoid specifying things like 11 and 6 at the
point of output. That's physical markup, and you want logical markup;
e.g. pressure, or volume. That way, you define in a single place
how pressure or volume are formatted, and if that formatting changes,
you don't have to search through out the program to find where to change
the format (and accidentally change the format of something else). In
C++, you do this by defining a manipulator, which sets the various
formatting options, and preferrably restores them at the end of the full
expression. So you end up writing things like:
std::cout << pressure << my_double;
Although I definitly wouldn't use it in production code, I've found the
following FFmt formatter useful for quicky jobs:
class FFmt : public StateSavingManip
{
public:
explicit FFmt(
int width,
int prec = 6,
std::ios::fmtflags additionalFlags
= static_cast<std::ios::fmtflags>(),
char fill = ' ' );
protected:
virtual void setState( std::ios& targetStream ) const;
private:
int myWidth;
int myPrec;
std::ios::fmtflags myFlags;
char myFill;
};
FFmt::FFmt(
int width,
int prec,
std::ios::fmtflags additionalFlags,
char fill )
: myWidth( width )
, myPrec( prec )
, myFlags( additionalFlags )
, myFill( fill )
{
myFlags &= ~ std::ios::floatfield
myFlags |= std::ios::fixed
if ( isdigit( static_cast< unsigned char >( fill ) )
&& (myFlags & std::ios::adjustfield) == 0 ) {
myFlags |= std::ios::internal
}
}
void
FFmt::setState(
std::ios& targetStream ) const
{
targetStream.flags( myFlags )
targetStream.width( myWidth )
targetStream.precision( myPrec )
targetStream.fill( myFill )
}
This allows writing things like:
std::cout << FFmt( 11, 6 ) << my_double;
And for the record:
class StateSavingManip
{
public:
StateSavingManip(
StateSavingManip const& other );
virtual ~StateSavingManip();
void operator()( std::ios& stream ) const;
protected:
StateSavingManip();
private:
virtual void setState( std::ios& stream ) const = 0;
private:
StateSavingManip& operator=( StateSavingManip const& );
private:
mutable std::ios* myStream;
mutable std::ios::fmtflags
mySavedFlags;
mutable int mySavedPrec;
mutable char mySavedFill;
};
inline std::ostream&
operator<<(
std::ostream& out,
StateSavingManip const&
manip )
{
manip( out );
return out;
}
inline std::istream&
operator>>(
std::istream& in,
StateSavingManip const&
manip )
{
manip( in );
return in;
}
StateSavingManip.cc:
namespace {
// We maintain the value returned by ios::xalloc() + 1, and not
// the value itself. The actual value may be zero, and we need
// to be able to distinguish it from the 0 resulting from 0
// initialization. The function getXAlloc() returns this value
// -1, so we add one in the initialization.
int getXAlloc();
int ourXAlloc = getXAlloc() + 1;
int
getXAlloc()
{
if ( ourXAlloc == 0 ) {
ourXAlloc = std::ios::xalloc() + 1;
assert( ourXAlloc != 0 );
}
return ourXAlloc - 1;
}
}
StateSavingManip::StateSavingManip()
: myStream( NULL )
{
}
StateSavingManip::StateSavingManip(
StateSavingManip const&
other )
{
assert( other.myStream == NULL );
}
StateSavingManip::~StateSavingManip()
{
if ( myStream != NULL ) {
myStream->flags( mySavedFlags );
myStream->precision( mySavedPrec );
myStream->fill( mySavedFill );
myStream->pword( getXAlloc() ) = NULL;
}
}
void
StateSavingManip::operator()(
std::ios& stream ) const
{
void*& backptr = stream.pword( getXAlloc() );
if ( backptr == NULL ) {
backptr = const_cast< StateSavingManip* >( this );
myStream = &stream;
mySavedFlags = stream.flags();
mySavedPrec = stream.precision();
mySavedFill = stream.fill();
}
setState( stream );
}
#include <iostream>
#include <iomanip>
int main() {
double my_double = 42.0;
std::cout << std::fixed << std::setw(11)
<< std::setprecision(6) << my_double << std::endl;
return 0;
}
For future visitors who prefer actual printf-style format specs with std::ostream, here is yet another variation, based on Martin York's excellent post in another SO question: https://stackoverflow.com/a/535636:
#include <iostream>
#include <iomanip>
#include <stdio.h> //snprintf
class FMT
{
public:
explicit FMT(const char* fmt): m_fmt(fmt) {}
private:
class fmter //actual worker class
{
public:
explicit fmter(std::ostream& strm, const FMT& fmt): m_strm(strm), m_fmt(fmt.m_fmt) {}
//output next object (any type) to stream:
template<typename TYPE>
std::ostream& operator<<(const TYPE& value)
{
// return m_strm << "FMT(" << m_fmt << "," << value << ")";
char buf[40]; //enlarge as needed
snprintf(buf, sizeof(buf), m_fmt, value);
return m_strm << buf;
}
private:
std::ostream& m_strm;
const char* m_fmt;
};
const char* m_fmt; //save fmt string for inner class
//kludge: return derived stream to allow operator overloading:
friend FMT::fmter operator<<(std::ostream& strm, const FMT& fmt)
{
return FMT::fmter(strm, fmt);
}
};
usage example:
double my_double = 42.0;
cout << FMT("%11.6f") << my_double << "more stuff\n";
or even:
int val = 42;
cout << val << " in hex is " << FMT(" 0x%x") << val << "\n";
it's me, the OP, Jive Dadson - five years on. C++17 is becoming a reality.
The advent of variadic template parameters with perfect forwarding has made life so much simpler. The chained madness of ostream<< and boost::format% can be dispensed with. The function oprintf below fills the bill. Work in progress. Feel free to chime in on error-handling, etc...
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <string_view>
namespace dj {
template<class Out, class... Args>
Out& oprintf(Out &out, const std::string_view &fmt, Args&&... args) {
const int sz = 512;
char buffer[sz];
int cx = snprintf(buffer, sz, fmt.data(), std::forward<Args>(args)...);
if (cx >= 0 && cx < sz) {
return out.write(buffer, cx);
} else if (cx > 0) {
// Big output
std::string buff2;
buff2.resize(cx + 1);
snprintf(buff2.data(), cx, fmt.data(), std::forward<Args>(args)...);
return out.write(buff2.data(), cx);
} else {
// Throw?
return out;
}
}
}
int main() {
const double my_double = 42.0;
dj::oprintf(std::cout, "%s %11.6lf\n", "My double ", my_double);
return 0;
}
Some great answers already; kudos to those!
This is based on some of them. I have added type assertions for POD types, since they are the only safe types usable with printf().
#include <iostream>
#include <stdio.h>
#include <type_traits>
namespace fmt {
namespace detail {
template<typename T>
struct printf_impl
{
const char* fmt;
const T v;
printf_impl(const char* fmt, const T& v) : fmt(fmt), v(v) {}
};
template<typename T>
inline typename std::enable_if<std::is_pod<T>::value, std::ostream& >::type
operator<<(std::ostream& os, const printf_impl<T>& p)
{
char buf[40];
::snprintf(buf, sizeof(buf), p.fmt, p.v, 40);
return os << buf;
}
} // namespace detail
template<typename T>
inline typename std::enable_if<std::is_pod<T>::value, detail::printf_impl<T> >::type
printf(const char* fmt, const T& v)
{
return detail::printf_impl<T>(fmt, v);
}
} // namespace fmt
Example usage it as below.
std::cout << fmt::printf("%11.6f", my_double);
Give it a try on Coliru.