C ++ библиотека с открытым исходным кодом для форматированного вывода таблицы - PullRequest
2 голосов
/ 27 октября 2011

Существует ли библиотека C ++ с открытым исходным кодом для форматирования таблиц?

То, что позволяет мне писать

Table t;// Table is a class provided by the library
t.column(2);
t.name(0,"x");
t.name(1,"x^2");
t.type("x",Table::Integer);
t.type("x^2",Table::Integer);
t.width("x",1);
t.width("x^2",2);
for( size_t i = 0; i < 10; i++ ) {
 t.set("x",i);
 t.set("x^2",i*i);
}
std::cout << t;

и получите этот текстовый вывод

0  0
1  1
2  4
3  9
4 16
5 25
6 36
7 49
8 64
9 81

Он должен быть способен управлять также числами с плавающей запятой, а не только целыми числами. Спасибо.

Ответы [ 2 ]

2 голосов
/ 27 октября 2011

Я не знаю ни о каких библиотеках.
Но вы можете перегрузить оператор << для вашего класса Table и добиться того же.

EDIT:
Чтобы уточнить, что ваш комментарий о том, что Table является классом библиотеки, не влияет на перегрузку <<, поскольку она перегружена как свободная функция non-member.

Пример кода:

std::ostream& operator<<(std::ostream& os, const Table& obj) 
{ 
  // write obj to stream in whichever way you like
  return os;
} 
1 голос
/ 27 октября 2011

Предустановленные библиотеки, о которых я знаю для такого рода вещей, в основном ориентированы на GUI, поэтому данные отображаются в виде электронных таблиц, а не просто в виде текста.

Рассмотрим ваше представление о том, какиспользовать библиотеку, мне кажется, что она плохо подходит для C ++.Имейте в виду, что C ++ использует статическую типизацию, где ваша t.type("x", Table::Integer) подразумевает динамическую типизацию (т. Е. Указывает тип этого столбца во время выполнения, а не во время компиляции).

Лично я бы, наверное, подумалс точки зрения объекта форматирования, который хранил информацию о форматировании для одного объекта.Тогда у вас будет «столбец» с объектом форматирования и вектором связанных данных.Наконец, у вас будет «таблица» с произвольным числом столбцов.Большая часть этого (особенно типы) будет указана в качестве аргументов шаблона, поэтому у вас может быть что-то вроде:

class format { 
    int w, p;
public:
    format(int width = 0, int precision = 0) : w(width), precision(p) {}

    friend std::ostream &operator<<(std::ostream &os, format const &f) { 
        return os << std::setw(f.w) << std::setprecision(f.p);
    }
};

template <class T, class container = std::vector<T> >
class Column {
    format f;
    std::string label;
    container data;
public:
    Column(std::string const &l, format const &fmt) : f(fmt), label(l) {}
    void push_back(T const &d) { data.push_back(d); }
};

format fmt1(1);
format fmt2(2);

Column<int> c1("x", fmt1);
Column<int> c2("x^2", fmt2);

table<2> my_table(c1, c2);

Я бы , вероятно, , затем спроектируйте таблицу так, чтобы она была примерноvector<tuple<values> >, поэтому, чтобы добавить значения, вы должны сделать что-то вроде:

for (int i=0; i<10; i++)
    my_table.push_back(make_tuple(i, i*i));

Возможно, вы использовали метод, который вы использовали (основываясь на имени столбца, а не на позиции),но очевидный способ (map<std::string, value>) будет работать только в том случае, если все столбцы будут одного типа.Чтобы поддерживать несколько типов столбцов, вы могли бы сделать что-то вроде map<std::string, boost::any>, но я бы держался подальше от этого, если это вообще разумно.

...