Is there are a better way than this one to print 2d table?
std::cout
<< std::setw(25) << left << "FF.name"
<< std::setw(25) << left << "BB.name"
<< std::setw(12) << left << "sw.cycles"
<< std::setw(12) << left << "hw.cycles" << "\n"
<< std::setw(25) << left << "------"
<< std::setw(25) << left << "------"
<< std::setw(12) << left << "---------"
<< std::setw(12) << left << "---------" << "\n";
You could put the headers into an array or vector, then generate the correct widths automatically:
boost::array<std::string, 4> head = { ... }
BOOST_FOREACH(std::string& s, head)
{
int w = 5*(s.length()/5 + 1);
std::cout << std::setw(w) << left << s;
}
std::cout << '\n';
BOOST_FOREACH(std::string& s, head)
{
int w = 5*(s.length()/5 + 1);
std::cout << std::string(w,'-');
}
std::cout << std::endl;
Might be worthwhile if you have lots of headers I guess.
Use printf. It's part of C, but it's still supported in C++.
Break things up into functions and it's not so bad.
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
typedef std::vector< std::string > StringVector;
void printRow( std::ostream& s, const StringVector& strings )
{
s << std::setw(25) << std::left << strings[ 0 ];
s << std::setw(25) << std::left << strings[ 1 ];
s << std::setw(12) << std::left << strings[ 2 ];
s << std::setw(12) << std::left << strings[ 3 ];
s << "\n";
}
void printHeadings( std::ostream& s, const StringVector& headings )
{
printRow( s, headings );
StringVector lines;
for ( StringVector::const_iterator H = headings.begin();
H != headings.end();
++H )
{
lines.push_back( std::string( H->size(), '-' ) );
}
printRow( s, lines );
}
int main()
{
StringVector headings( 4 );
headings[ 0 ] = "FF.name";
headings[ 1 ] = "BB.name";
headings[ 2 ] = "sw.cycles";
headings[ 3 ] = "hw.cycles";
printHeadings( std::cout, headings );
StringVector contents( 4 );
contents[ 0 ] = "foo";
contents[ 1 ] = "bar";
contents[ 2 ] = "baz";
contents[ 3 ] = "foobarbaz";
printRow( std::cout, contents );
return 0;
}
Note that I've left out the bounds checking on the string vectors since this is only intended as an example.
Width is the only formatting setting that gets reset, so you can trivially simplify to:
std::cout << left;
std::cout
<< std::setw(25) << "FF.name"
<< std::setw(25) << "BB.name"
<< std::setw(12) << "sw.cycles"
<< std::setw(12) << "hw.cycles"
<< "\n";
You might like:
//...
std::cout << w(25, "FF.name");
//...
// implemented:
template<class T>
struct AtWidth {
std::streamsize width;
T const& obj;
AtWidth(std::streamsize width, T const& obj) : width(width), obj(obj) {}
template<class Stream> // easier than templating on basic_stream
friend Stream& operator<<(Stream& s, AtWidth const& value) {
s.width(value.width);
return s << value.obj;
}
};
template<class T>
AtWidth<T> w(std::streamsize width, T const& obj) {
return AtWidth<T>(width, obj);
}
Or if you want to rename the setw function (C++0x):
auto w(std::streamsize width) -> decltype(std::setw(width)) {
return std::setw(width);
}
// ...
std::cout << w(25) << "FF.name";
(In non-0x, you'd have to either know how your library implements setw to get the right type or re-write it yourself, which isn't too hard, BTW.)
Edit: I missed the second line of dashes here, another answer covers that well enough. The solution for that is indeed to construct a header "object" and print it out more or less at once.
Related
I would like to use the ftw-function to recursivly traverse a filesystem structure. Additionally, the method shall be used inside of a class. Also, the entry-function, which is called by nftw(), belongs to the same class. That needs to be the case because the entry-function is supposed to change some class-members, dependent on the files that it finds.
When implementing such an approach, I get an error (see below). Is this an issue of syntax or is it not even possible to forward a pointer to a method to nftw()? In case it is not possible, do you know any alternative way to resursivly traverse a filesystem structure under linux?
class model
{
public:
boost::unordered_map<std::string, int> map;
int configure(const char *name)
{
// ...
ftw("DTModels/", this->ftw_entry, 15);
// ...
return = 0;
}
private:
int ftw_entry(const char *filepath, const struct stat *info, const int typeflag)
{
// Here I want to change the member 'map'
std::string filepath_s = filepath;
std::cout << "FTW_Entry: " << filepath_s << std::endl;
}
};
ERROR:
a pointer to a bound function may only be used to call the function
ftw("DTModels/", this->ftw_entry, 15);
I haven't used ftw in many many years and since you ask for an alternative, take a look at std::filesystem (C++17). Many pre-C++17 installations have it available via boost or experimental. If you use one of the pre-C++17 implementations, you many need to remove some of the stat lines from the below to make it work.
#include <iostream>
//#define I_HAVE_BOOST
#if __cplusplus >= 201703L
#include <filesystem>
namespace fs = std::filesystem;
#elif I_HAVE_BOOST
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
#else
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#endif
auto& out = std::cout;
void show_dent(const fs::directory_entry& dent) {
static size_t indent=0;
std::string ind(indent, ' ');
fs::file_status lstat = dent.symlink_status();
if( fs::is_symlink(lstat) ) {
fs::path pp = fs::read_symlink(dent);
out << ind << dent << " -> " << pp << "\n";
++indent;
show_dent(fs::directory_entry(pp));
--indent;
} else {
if(fs::is_directory(dent)) {
fs::directory_iterator dit_end;
std::cout << "Directory " << dent << " includes the following files:\n";
++indent;
for(auto dit = fs::directory_iterator(dent); dit != dit_end; ++dit) {
show_dent(*dit);
}
--indent;
} else {
fs::file_status stat = dent.status();
out << ind << dent << "\n"
<< ind << " stat\n"
<< ind << " is_regular_file : " << fs::is_regular_file(stat) << "\n"
<< ind << " is_directory : " << fs::is_directory(stat) << "\n"
<< ind << " is_block_file : " << fs::is_block_file(stat) << "\n"
<< ind << " is_character_file: " << fs::is_character_file(stat) << "\n"
<< ind << " is_fifo : " << fs::is_fifo(stat) << "\n"
<< ind << " is_socket : " << fs::is_socket(stat) << "\n"
<< ind << " is_symlink : " << fs::is_symlink(stat) << "\n"
<< ind << " exists : " << fs::exists(stat) << "\n";
if( fs::is_regular_file(stat) ) {
out
<< ind << " file_size : " << fs::file_size(dent) << "\n";
}
}
}
}
int main(int argc, char* argv[]) {
std::vector<std::string> args(argv+1, argv+argc);
out << std::boolalpha;
for(const auto& file_or_dir : args) {
show_dent(fs::directory_entry(file_or_dir));
}
return 0;
}
I have the following json file
[
{
"a":5855925.424944928,
"b":0,
"c":96,
"d":2096640,
"e":0
}
]
I do this,
boost::property_tree::ptree jsontree;
std::stringstream ss;
ss << "[{\"a\": 5855925.424944928, \"b\": 0, \"c\": 96, \"d\": 2096640, \"e\": 0}]";
boost::property_tree::read_json(ss, jsontree);
// get the children, i.e. the list elements
auto bounds = jsontree.equal_range("");
std::cout << "Size of list : " << std::distance( bounds.first, bounds.second ) << "\n";
But I don't know how to read this from a property tree (eg: get<float>("a"), get<int>("c"))?
Any help would be greatly appreciated.
Thanks
Notice: top-level arrays are not actually supported (you cannot roundtrip that with Boost Property Tree).
The limitations are described in the documentation
Saving this same tree will lose all type information and convert the array to this:
{
"": {
"a": "5855925.424944928",
"b": "0",
"c": "96",
"d": "2096640",
"e": "0"
}
}
Arrays are "objects with empty keys". You already seemed to know that, judging from your sample. So, just use it:
for (auto& object_node : boost::make_iterator_range(jsontree.equal_range(""))) {
ptree const& object = object_node.second;
std::cout << "a: " << object.get<double>("a") << "\n";
std::cout << "b: " << object.get<int>("b") << "\n";
std::cout << "c: " << object.get<int>("c") << "\n";
std::cout << "d: " << object.get<int>("d") << "\n";
std::cout << "e: " << object.get<int>("e") << "\n";
}
Improved Demo
It's often nicer to extract some types/functions:
Live On Coliru
#include <iostream>
#include <boost/property_tree/json_parser.hpp>
using boost::property_tree::ptree;
struct Object {
double a;
int b, c, d, e;
friend std::ostream& operator<<(std::ostream& os, Object const& object) {
return os << "a: " << object.a << "\n"
<< "b: " << object.b << "\n"
<< "c: " << object.c << "\n"
<< "d: " << object.d << "\n"
<< "e: " << object.e << "\n";
}
static Object parse(ptree const& from) {
return {
from.get<double>("a"),
from.get<int>("b"),
from.get<int>("c"),
from.get<int>("d"),
from.get<int>("e"),
};
}
};
int main() {
boost::property_tree::ptree jsontree;
{
std::stringstream ss(R"([{"a": 5855925.424944928, "b": 0, "c": 96, "d": 2096640, "e": 0}])");
boost::property_tree::read_json(ss, jsontree);
}
for (auto& object_node : boost::make_iterator_range(jsontree.equal_range(""))) {
std::cout << Object::parse(object_node.second);
}
}
Prints
a: 5.85593e+06
b: 0
c: 96
d: 2096640
e: 0
You can use BOOST_FOREACH for this. I am attaching some code but they are based on xml_data. But u can use similar to this for getting each value without knowing the key.
BOOST_FOREACH(pt::ptree::value_type &v, tree) {
std::string at = v.first + ATTR_SET;
std::cout << "Extracting attributes from " << at << ":\n";
BOOST_FOREACH(pt::ptree::value_type &v2,v.second.get_child("<xmlattr>")){
std::cout<<""<<v2.first.data()<<" : " <<v2.second.data()<<"\n";
}
std::cout<<"now in book\n";
BOOST_FOREACH(pt::ptree::value_type &v3,tree.get_child("bookstore."+v.first)){
std::cout<<""<<v3.first.data()<<" : " <<v3.second.data()<<"\n";
}
m_modules.insert(v.second.data());
}
here tree is boost::Property_tree::ptree
I've been trying to write a simple allocator, I've written a minimal one that just logs its calls.
When trying to use it in some simple std::vector operations - at least on GCC and Visual Studio - the logged behaviour looks intuitive except that the destructor appears to be called before all of the allocations are requested, as well as at the end. On clang everything works as one would expect, so I'm not sure if this is just a compiler issue.
Assuming it's not a compiler error, what's missing from this allocator; or is my understanding of how the allocator is being called wrong and it's just fine?
I have the code below as a live demo here
#include <ios>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using std::size_t;
struct Indexer
{
static size_t nextId, objectsAlive;
};
size_t Indexer::nextId, Indexer::objectsAlive;
template<typename T>
class DebugAllocator : protected Indexer
{
static std::string formatPointer(const void* p)
{
std::ostringstream s;
s << "[93m0x" << std::hex << std::uppercase << uintptr_t(p) << "[0m";
return s.str();
}
static std::string formatFunctionName(const char* functionName)
{
return "[96m" + std::string(functionName) + "[0m";
}
static std::string indentation()
{
return std::string((objectsAlive + 1) * 4, ' ');
}
public:
using value_type = T;
using pointer = value_type*;
using size_type = std::make_unsigned_t<typename std::pointer_traits<pointer>::difference_type>;
size_t id;
DebugAllocator() noexcept
: id(nextId++)
{
std::cerr << indentation() << "DebugAllocator::" << formatFunctionName(__func__) << '(' << id << ")\n";
++objectsAlive;
}
template<typename T_rhs>
DebugAllocator(const DebugAllocator<T_rhs>& rhs) noexcept
: id(nextId++)
{
std::cerr << indentation() << "DebugAllocator::" << formatFunctionName(__func__) << '(' << id << ", " << rhs.id << ")\n";
++objectsAlive;
}
template<typename T_rhs>
DebugAllocator& operator=(const DebugAllocator<T_rhs>& rhs) noexcept
{
std::cerr << indentation() << id << " = DebugAllocator::" << formatFunctionName(__func__) << '(' << id << ", " << rhs.id << ")\n";
}
~DebugAllocator() noexcept
{
--objectsAlive;
std::cerr << indentation() << "DebugAllocator::" << formatFunctionName(__func__) << '(' << id << ")\n";
}
pointer allocate(size_type n) const
{
value_type* const p((value_type*) new char[sizeof(value_type) * n]);
std::cerr << indentation() << formatPointer(p) << " = DebugAllocator::" << formatFunctionName(__func__) << '(' << id << ", " << n << ")\n";
return p;
}
void deallocate(pointer p, size_type n) const noexcept
{
std::cerr << indentation() << "DebugAllocator::" << formatFunctionName(__func__) << '(' << id << ", " << formatPointer(p) << ", " << n << ")\n";
delete[] (value_type*) p;
}
bool operator==(const DebugAllocator& rhs) const noexcept
{
std::cerr << indentation() << std::boolalpha << true << " = DebugAllocator::" << formatFunctionName(__func__) << '(' << id << ", " << rhs.id << ")\n";
return true;
}
bool operator!=(const DebugAllocator& rhs) const noexcept
{
std::cerr << indentation() << std::boolalpha << false << " = DebugAllocator::" << formatFunctionName(__func__) << '(' << id << ", " << rhs.id << ")\n";
return false;
}
};
int main()
{
std::vector<int, DebugAllocator<int>> v{3};
v.push_back(1);
v.push_back(2);
v.emplace_back(1);
v.insert(std::begin(v) + 2, 4);
v.erase(std::begin(v) + 3);
std::string separator;
for (int& x : v)
{
std::cerr << separator << std::move(x);
separator = ", ";
}
std::cerr << '\n';
}
GCC / MSVS log:
DebugAllocator::DebugAllocator(0)
0xF86C50 = DebugAllocator::allocate(0, 1)
DebugAllocator::~DebugAllocator(0)
0xF86CA0 = DebugAllocator::allocate(0, 2)
DebugAllocator::deallocate(0, 0xF86C50, 1)
0xF86C50 = DebugAllocator::allocate(0, 4)
DebugAllocator::deallocate(0, 0xF86CA0, 2)
0xF86C20 = DebugAllocator::allocate(0, 8)
DebugAllocator::deallocate(0, 0xF86C50, 4)
3, 1, 4, 1
DebugAllocator::deallocate(0, 0xF86C20, 8)
DebugAllocator::~DebugAllocator(0)
clang log:
DebugAllocator::DebugAllocator(0)
0xD886F0 = DebugAllocator::allocate(0, 1)
0xD88710 = DebugAllocator::allocate(0, 2)
DebugAllocator::deallocate(0, 0xD886F0, 1)
0xD886F0 = DebugAllocator::allocate(0, 4)
DebugAllocator::deallocate(0, 0xD88710, 2)
0xD88730 = DebugAllocator::allocate(0, 8)
DebugAllocator::deallocate(0, 0xD886F0, 4)
3, 1, 4, 1
DebugAllocator::deallocate(0, 0xD88730, 8)
DebugAllocator::~DebugAllocator(0)
Apparently
template<typename T_rhs>
DebugAllocator(const DebugAllocator<T_rhs>& rhs)
does not count as a copy constructor. So a compiler-generated copy-constructor is called that you didn't observe.
I just want to format a string and an integer value with right justify.
There is no problem to do this without leading space before the integer value.
bytes.....................123981
total bytes..............1030131
But it should look like this:
bytes ................... 123981
total bytes ............ 1030131
Unfortunately the example below wont work, because setw (right justify) relates only to the next stream element.
int iBytes = 123981;
int iTotalBytes = 1030131;
cout << setfill('.');
cout << right;
cout << "bytes " << setw(20) << " " << iBytes << endl;
cout << "total bytes " << setw(14) << " " << iTotalBytes << endl;
I hardly ever use std::cout, so is there a simple way to do this without previously joining a space char to the value?
The simplest way would be to write your " " and value into a std::stringstream and write the resulting str() into your output stream like:
std::stringstream ss;
ss << " " << iBytes;
cout << "bytes " << setw(20) << ss.str() << endl;
And here comes the complete overkill. A templated class prefixed which can be printed and bundles the two constructor arguments prefix,val into one string to be printed. number format, and precision is taken from the final output stream. Works with ints,floats, strings and const char *. And should work with every arg that has a valid output operator.
#include <fstream>
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
template<class T>
class prefixed_base {
public:
prefixed_base(const std::string & prefix,const T val) : _p(prefix),_t(val) {
}
protected:
std::string _p;
T _t;
};
// Specialization for const char *
template<>
class prefixed_base<const char*> {
public:
prefixed_base(const std::string & prefix,const char * val) : _p(prefix),_t(val) {
}
protected:
std::string _p;
std::string _t;
};
template<class T>
class prefixed : public prefixed_base<T> {
private:
typedef prefixed_base<T> super;
public:
prefixed(const std::string & prefix,const T val) : super(prefix,val) {
}
// Output the prefixed value to an ostream
// Write into a stringstream and copy most of the
// formats from os.
std::ostream & operator()(std::ostream & os) const {
std::stringstream ss;
// We 'inherit' all formats from the
// target stream except with. This Way we
// keep informations like hex,dec,fixed,precision
ss.copyfmt(os);
ss << std::setw(0);
ss << super::_p;
ss.copyfmt(os);
ss << std::setw(0);
ss << super::_t;
return os << ss.str();
}
};
// Output operator for class prefixed
template<class T>
std::ostream & operator<<(std::ostream & os,const prefixed<T> & p) {
return p(os);
}
// This function can be used directly for output like os << with_prefix(" ",33.3)
template<class T>
prefixed<T> with_prefix(const std::string & p,const T v) {
return prefixed<T>(p,v);
}
int main() {
int iBytes = 123981;
int iTotalBytes = 1030131;
cout << setfill('.');
cout << right;
cout << "bytes " << setw(20) << with_prefix(" ",iBytes) << endl;
cout << "total bytes " << setw(14) << with_prefix(" ",iTotalBytes) << endl;
cout << "bla#1 " << setw(20) << std::fixed << std::setprecision(9) << with_prefix(" ",220.55) << endl;
cout << "blablabla#2 " << setw(14) << std::hex << with_prefix(" ",iTotalBytes) << endl;
}
#Oncaphillis thx for the piece of source code, I adapt it a bit for my needs. I just wrote a function to convert values. std::to_string is used by C++11 standard, so I decided to use _to_string/_to_wstring instead. The tricky part was to get "wcout" to work with UNICODEs on Windows console. I didn’t really manage it, so I had to do a workaround. Anyway to print e.g. Cyrillic characters you have to change the console font to Consolas or Lucida.
#include <windows.h>
#include <tchar.h>
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
#if defined(UNICODE) || defined(_UNICODE)
#define _tcout std::wcout
#define _to_tstring _to_wstring
template <typename T>std::wstring _to_wstring(const T& value) {
std::wostringstream wos;
wos.copyfmt(std::wcout);
wos << value;
return wos.str();
}
#else
#define _tcout std::cout
#define _to_tstring _to_string
template <typename T> std::string _to_string(const T& value) {
std::ostringstream os;
os.copyfmt(std::cout);
os << value;
return os.str();
}
#endif
int _tmain(int argc, _TCHAR* argv[]) {
int iBytes = 123981;
int iTotalBytes = 1030131;
#if defined(UNICODE) || defined(_UNICODE)
wostringstream newCoutBuffer;
wstreambuf* oldCoutBuffer = _tcout.rdbuf(newCoutBuffer.rdbuf()); // redirect cout buffer
#endif
_tcout.imbue(std::locale("German")); // enable thousand separator
_tcout.precision(0);
_tcout << setfill(_T('.')) << right << fixed;
_tcout << _T("bytes ") << setw(20) << _T(" ") + _to_tstring(iBytes) << endl;
_tcout << _T("bytes total ") << setw(14) << _T(" ") + _to_tstring(iTotalBytes) << endl;
_tcout << _T("bla bla ") << fixed << setprecision(9); _tcout << setw(18) << _T(" ") + _to_tstring(0.1337) << endl;
_tcout << _T("Милые женщины ") << hex; _tcout << setw(12) << _T(" ") + _to_tstring(iTotalBytes) << endl;
_tcout << _T("retries ") << dec; _tcout << setw(18) << _T(" ") + _to_tstring(2) + _T(" of ") + _to_tstring(20) << endl;
#if defined(UNICODE) || defined(_UNICODE)
DWORD dwWritten;
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), newCoutBuffer.str().c_str(),newCoutBuffer.tellp(),&dwWritten,NULL);
_tcout.rdbuf(oldCoutBuffer);
#endif
return 0;
}
Output:
bytes ............ 123.981
bytes total .... 1.030.131
bla bla ...... 0,133700000
Милые женщины ..... fb.7f3
retries .......... 2 of 20
In this program, I am using template class, I have a header file and this is my main file. I am having trouble displaying the (".....") IndexOutOfBounds and displaying it on the screen.
#include "XArray.h"
#include <iomanip>
#include <string>
using namespace std;
template<class T>
void afriend ( XArray<T> );
int main()
{
XArray<double> myAD(18);
myAD.randGen(15, 100);
cout << myAD.getType() << endl;
cout << setprecision(1) << fixed << "\n\n Unsorted: " << myAD;
myAD.sort();
cout << "\n Now Sorted: " << myAD;
cout << "\n\n";
**try
{
cout << "A[-5] = " << setw(6) << myAD[-5] << endl;
}
catch(XArray<double>::IndexOutOfBound e)
{
e.print();
}
try
{
cout << "A[8] = " << setw(6) << myAD[8] << endl;
}
catch(XArray<double>::IndexOutOfBound e)
{
e.print();
}**
cout << "\n\n" << setprecision(2) << fixed;
cout << "Size = " << setw(6) << myAD.getSize() << endl;
cout << "Mean = " << setw(6) << myAD.mean() << endl;
cout << "Median = " << setw(6) << myAD.median() << endl;
cout << "STD = " << setw(6) << myAD.std() << endl;
cout << "Min # = " << setw(6) << myAD.min() << endl;
cout << "Max # = " << setw(6) << myAD.max() << endl;
return 0;
}
There is the Array.h file posted as a dropbox link
Array.h
The code for operator[] in Array.h is:
template <class T>
T XArray<T>::operator[] (int idx)
{
if( (idx = 0) && (idx < size) )
{
return Array[idx];
}
else
{
throw IndexOutOfBound();
return numeric_limits<T>::epsilon();
}
}
Although the question is somewhat obscure, give a try to these suggestions.
Firstly, it can happen that XArray<>::IndexOutOfBounds have no proper copy ctor. You can try catching by const reference to workaround that:
try
{
...
}
catch(const XArray<double>::IndexOutOfBound& e)
{
e.print();
}
Index operator in standard library containers does not check for bounds, there is a special getter that does the check called at(). If the XArray class is designed with standard library in mind, it could behave similarly.
However to get more adequate response you need to be more specific describing the trouble you are having.
I'm still wondering what exact question is.
However, I'm understanding the question is that how I can use 'catch' by using 'IndexOutOfBound'.
#include <exception>
#include <iostream>
using namespace std;
template <typename T>
class Array
{
private:
int m_nLength;
T *m_ptData;
public:
...
...
T& operator[](int nIndex)
{
//assert(nIndex >= 0 && nIndex < m_nLength);
if(nIndex < 0 || nIndex > m_nLength)
{
throw myex;
}
else
{
return m_ptData[nIndex];
}
}
//class definition for 'IndexOutOfBound'
class IndexOutOfBound: public exception
{
public:
virtual const char* print() const throw()
{
return "Exception occured 'Index Out Of Bound'";
}
}myex;
};
int main()
{
Array<double> arr(3);
try
{
arr[0] = 1;
//exception will occur here.
arr[4] = 2;
}
catch(Array<double>::IndexOutOfBound &e)
{
cout << e.print() << '\n';
}
return 0;
}
Here is no 'XArray.h', so I've written a sample array class for example.
The problem is in the operator[] function. The code idx = 0 sets idx to 0. So all of your calls to operator[] will return the first element, and therefore there is no out-of-bounds error unless the array is empty.
You probably meant to write if ( idx >= 0 && idx < size ).
BTW the throw aborts the function, it makes no sense to return after throw.