Often when working with C++ I find myself wanting to quickly plot the contents of a vector with something like matplotlib
. When working in an interpertive Python environment such as IPython or an IPython notebook, quickly generating plots for "sanity checks" frequently only involves a few lines of code. For example:
# some programming....
In [60]: print v[0:10]
[ 0. 0.09983342 0.19866933 0.29552021 0.38941834 0.47942554
0.56464247 0.64421769 0.71735609 0.78332691]
In [61]: plt.plot(v)
In [62]:
# keep working away...
For a similar experience when working with C++ I have found it handy to be able to dump the contents of a vector to std::cout
in a format that can be directly copy/pasted into a Python script or interperter. To that end, I have written a template function that will take a vector and create a comma separated string using the vector's contents.
Below is a sample program demonstrating the function. An alternative version boost::lexical_cast
shown but commented out. While boost::lexical_cast
is more consise, there is less formatting control.
// sample.cpp
// To compile and run:
// $ g++ sample.cpp
// $ ./a.out
// vector_of_ints = [0, 0, 0, 0, 0]
// vector_of_floats = [0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00]
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <vector>
//#include <boost/lexical_cast.hpp>
/** Template function that generates a comma separated string from the contents of
* a vector. Elements are separated by a comma and a space for readability.
*/
template<typename T>
std::string vec2csv(const std::vector<T>& vec) {
std::string s;
for (typename std::vector<T>::const_iterator it = vec.begin(); it != vec.end(); ++it) {
// Simpler, but requires boost and offers minimal formatting control
//s += boost::lexical_cast<std::string>(*it);
// Doesn't require boost, offers more formatting control
std::ostringstream ss;
ss << std::fixed << std::setprecision(2);
ss << *it;
s += ss.str();
s += ", ";
}
if (s.size() >= 2) { // clear the trailing comma, space
s.erase(s.size()-2);
}
return s;
}
int main() {
std::vector<int> v_ints(5);
std::vector<float> v_flts(10);
std::cout << "vector_of_ints = [" << vec2csv(v_ints) << "]" << std::endl;
std::cout << "vector_of_floats = [" << vec2csv(v_flts) << "]" << std::endl;
return 0;
}