-46 / 3 / 0
Регистрация: 17.12.2011
Сообщений: 608

Как вывести данные базы данных в табличном виде?

06.10.2025, 15:05. Показов 979. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Подскажите, пожалуйста, как вывести двнные базы данных в табличном виде? (прикрепляю примеры).

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// ...
namespace school
{
    MySQLConnection::MySQLConnection(const std::string& host, int port,
        const std::string& user, const std::string& password,
        const std::string& database) {
 
        sql::mysql::MySQL_Driver* driver = sql::mysql::get_mysql_driver_instance();
        std::string connectionString = "tcp://" + host + ":" + std::to_string(port);
 
        connection.reset(driver->connect(connectionString, user, password));
        connection->setSchema(database);
    }
 
    void MySQLConnection::executeQuery(const std::string& query) {
        std::unique_ptr<sql::Statement> stmt(connection->createStatement());
        std::unique_ptr<sql::ResultSet> res(stmt->executeQuery(query));
 
        while (res->next()) {
            // Обработка результатов
            std::cout << "Результат: " << res->getString(1) << " | " << res->getString(2) << " | " << res->getString(3) << " | " << res->getString(4) << " | " << res->getString(5) << std::endl;
        }
    }
 
    bool MySQLConnection::isConnected() {
        return connection.get() != nullptr && !connection->isClosed();
    }
}
Миниатюры
Как вывести данные базы данных в табличном виде?   Как вывести данные базы данных в табличном виде?  
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
06.10.2025, 15:05
Ответы с готовыми решениями:

Перенос данных из StringGrid в FastReport в табличном виде, для формирования отчёта
Добрый день! Помогите решить задачку, имеется на форме String Grid, как его перенести в FastReport...

Функция print для вывода структурированных данных в табличном виде
Создайте функцию print, void print(double value=5, char*name2=&quot;Семенов &quot;, char*name1=&quot;Студент: &quot;,...

Составить программу, которая выводит в табличном виде результат вычисления функций y1(x), y2(x), y3(x) и y4(x)

7
Нарушитель
4085 / 2974 / 813
Регистрация: 29.06.2020
Сообщений: 10,988
06.10.2025, 16:09
Где то были такие темки, про эти таблички
Создаем универсальное средство форматирование, под разные задачи и настройками.
Просто как пример по ссылке этой ссылки : Исправить имеющийся вывод на вывод в виде таблицы

Добавлено через 11 минут
В теории всё просто:
есть два распространенных варианта, которые неоднократно обсуждались и реализовывались.
1. Заранее выбрать фиксированную ширину "столбцов", гарантированно больших их содержимого.
2. Формировать таблицу, анализируя все данные и только после этого, зная все размеры столбцов, генерировать таблицу.
В реализации, на сколько нужна детализация, гибкость настройки и желания всё это делать.
У меня желания нет.
0
-46 / 3 / 0
Регистрация: 17.12.2011
Сообщений: 608
07.10.2025, 13:10  [ТС]
Подскажите, пожалуйста, почему на экран ничего не выводится?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
 
#define l(v) std::wcout << #v << " = " << (v) << "\n";
 
// Класс-обертка для преобразования в строку
class StringConverter
{
public:
    template<typename T>
    static std::wstring toString(T val)
    {
        std::wostringstream oss;
        oss << val;
        return oss.str();
    }
};
 
// Класс для работы со строками
class MyString : public std::wstring
{
public:
    MyString() : std::wstring() {}
    MyString(std::wstring s) : std::wstring(s) {}
    MyString(const wchar_t* s) : std::wstring(s) {}
 
    template<typename T>
    MyString& operator=(const T a)
    {
        *this = StringConverter::toString(a);
        return *this;
    }
};
 
// Класс для работы с вектором
template<typename T>
class MyVector : public std::vector<T>
{
public:
    T& operator[](const size_t i)
    {
        if (i >= this->size()) this->resize(i + 1);
        return *(this->begin() + i);
    }
 
    void resize(size_t new_size, const T& value = T())
    {
        std::vector<T>::resize(new_size, value);
    }
};
 
// Класс для форматирования таблицы
class TableFormatter
{
private:
    size_t CMAX;
    MyVector<MyVector<MyString>>& m;
    MyVector<MyString>& h;
 
public:
    TableFormatter(size_t& cmax, MyVector<MyVector<MyString>>& data,
        MyVector<MyString>& header)
        : CMAX(cmax), m(data), h(header) {
    }
 
    void format()
    {
        calculateMaxColumns();
        resizeRows();
        addRowNumbers();
        calculateColumnWidths();
        alignColumns();
        alignHeaders();
    }
 
private:
    void calculateMaxColumns()
    {
        for (const auto& e : m)
            if (CMAX < e.size())
                CMAX = e.size();
    }
 
    void resizeRows()
    {
        for (auto& e : m)
            if (CMAX > e.size())
                e.resize(CMAX);
 
        if (CMAX > h.size())
            h.resize(CMAX);
    }
 
    void addRowNumbers()
    {
        for (size_t r = 0; r < m.size(); ++r)
        {
            m[r][0] = StringConverter::toString(r + 1);
        }
    }
 
    void calculateColumnWidths()
    {
        std::vector<size_t> n(CMAX, 0);
 
        // Инициализация ширинами заголовков
        for (size_t i = 0; i < h.size() && i < CMAX; ++i)
        {
            n[i] = h[i].size();
        }
 
        // Нахождение максимальных ширин
        for (size_t c = 0; c < CMAX; ++c)
        {
            for (size_t r = 0; r < m.size(); ++r)
            {
                if (n[c] < m[r][c].size())
                    n[c] = m[r][c].size();
            }
        }
 
        // Выравнивание столбцов
        for (size_t c = 0; c < CMAX; ++c)
        {
            for (size_t r = 0; r < m.size(); ++r)
            {
                if (n[c] > m[r][c].size())
                    m[r][c].resize(n[c], ' ');
            }
        }
 
        // Выравнивание заголовков
        for (size_t c = 0; c < CMAX; ++c)
        {
            if (h[c].size() < m[0][c].size())
                h[c].resize(m[0][c].size(), ' ');
        }
    }
 
    void alignColumns() {} // Заглушка для совместимости с логикой
    void alignHeaders() {} // Заглушка для совместимости с логикой
};
 
// Класс для вывода таблицы
class TablePrinter
{
private:
    MyVector<MyVector<MyString>>& m;
    MyVector<MyString>& h;
    size_t& CMAX;
 
public:
    TablePrinter(MyVector<MyVector<MyString>>& data,
        MyVector<MyString>& header, size_t& cmax)
        : m(data), h(header), CMAX(cmax) {
    }
 
    void print(std::wostream& o)
    {
        std::wstring line = createLine();
 
        o << line << '\n';
        printHeader(o);
        o << '\n' << line << '\n';
        printRows(o);
        o << line << '\n' << '\n';
    }
 
private:
    std::wstring createLine()
    {
        std::wstring line;
        for (size_t c = 0; c < CMAX; ++c)
        {
            line += std::wstring(h[c].size() + 3, '=');
        }
        return line;
    }
 
    void printHeader(std::wostream& o)
    {
        for (size_t c = 0; c < CMAX; ++c)
        {
            o << ' ' << h[c] << " |";
        }
    }
 
    void printRows(std::wostream& o)
    {
        for (const auto& r : m)
        {
            for (const auto& e : r)
            {
                o << ' ' << e << " |";
            }
            o << '\n';
        }
    }
};
 
// Основной класс таблицы
class Tab
{
private:
    MyVector<MyVector<MyString>> m;
    MyVector<MyString> h;
    size_t CMAX = 0;
 
public:
    Tab() = default;
 
    MyVector<MyString>& operator[](const size_t i)
    {
        if (i >= m.size()) m.resize(i + 1);
        return *(m.begin() + i);
    }
 
    template<typename ... T>
    void head(T ... t)
    {
        (h.push_back(StringConverter::toString(t)), ...);
    }
 
    void formater()
    {
        TableFormatter formatter(CMAX, m, h);
        formatter.format();
    }
 
    friend std::wostream& operator<<(std::wostream&, Tab&);
};
 
std::wostream& operator<<(std::wostream& o, Tab& t)
{
    t.formater();
 
    TablePrinter printer(t.m, t.h, t.CMAX);
    printer.print(o);
 
    return o;
}
 
///----------------------------------------------------------------------------|
/// Тест.
///----------------------------------------------------------------------------:
class TabTest
{
public:
    void run()
    {
        ///-----------------------|
        /// Создаём табулятор.    |
        ///-----------------------:
        Tab tab;
 
        ///-----------------------|
        /// Заголовок.            |
        ///-----------------------:
        tab.head(L"NN", L"Первый", L"Второй", 3);
 
        ///-----------------------|
        /// Как угодно заполняем. |
        ///-----------------------:
        tab[1][1] = 2020;
        tab[2][2] = "qwerty";
        tab[4][3] = 3.14;
        tab[0][4] = L"Яша + Оля";
 
        ///-----------------------|
        /// Вывод на экран/файл.  |
        ///-----------------------:
        std::wcout << tab;
        std::wcout << tab;
    }
};
 
///----------------------------------------------------------------------------|
/// Старт.
///----------------------------------------------------------------------------:
int main()
{
    setlocale(0, "");
 
    TabTest test;
    test.run();
 
    return 0;
}
0
Нарушитель
4085 / 2974 / 813
Регистрация: 29.06.2020
Сообщений: 10,988
07.10.2025, 14:22
DDim1000, тот пример, был приведен с учетом работы с широкими строками, не utf8.
Для вывода таких строк через wcout, setlocale(0, "") - этого не достаточно.

Оригинальный код по ссылке корректно работает на Windows со след. настройками консоли (для ввода вывода широких строк).
C++
1
2
3
4
5
6
7
#include <fcntl.h>
#include <io.h>
 
int main{
     _setmode( _fileno( stdin ), _O_U16TEXT );
     _setmode( _fileno( stdout ), _O_U16TEXT );
     _setmode( _fileno( stderr ), _O_U16TEXT );
А в приведенном тобой коде, ошибки нужно искать. Если включить отображение всех предупреждений (опция компилятора /Wall), то ошибка явно тонкая.

Теперь плавно подошли к тому, какую же кодировку использовать внутри данной программы.
Это напрямую зависит от задач/и.
Но в общем случае, я бы рекомендовал внутри приложения использовать wstring, широкие строки.
Это означает что при работе с внешними библиотеками, такими как mysql и другими, которые получают отдают utf8 строки, придется конвертировать в широкие и обратно.
Это нормально.

Ошибку в коде поищу, но обещать ничего не буду.
Ох. Посмотрел предупреждения и код.
C++
29
30
31
32
33
34
    template<typename T>
    MyString& operator=(const T a)
    {
        *this = StringConverter::toString(a);
        return *this;
    }
Code
1
2
c:\tmp\tmp2\probe.cpp(37) : warning C4717: MyString::operator=<std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >: рекурсия на всех путях выполнения, функция вызовет переполнение стека
c:\tmp\tmp2\probe.cpp(114) : warning C5045: Компилятор вставит компонент устранения рисков Spectre для загрузки памяти, если указан параметр /Qspectre
Тут какая то бесконечная рекурсия.
0
Нарушитель
4085 / 2974 / 813
Регистрация: 29.06.2020
Сообщений: 10,988
09.10.2025, 20:43
Можно взять за основу этот код.
По востребованию, могу дополнить и написать комментарии к коду.
Почти не реализован вывод рамок, нет установки выравнивания, отступы игнорируются, отсутствует поддержка многострочных данных.
Нет установки минимальной/максимальной ширини.
Отсутствует шапка.
Всё это можно реализовать.
Возможно будет позже.
https://onlinegdb.com/nc655NOZn
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include <iostream>
#include <string>
#include <tuple>
#include <vector>
#include <sstream>
#include <cstdint>
#include <cstddef>
#include <array>
#include <iomanip>
 
namespace Table{
   
template <typename F, typename TupleT, std::size_t... Is>
void apply(F&& f, const TupleT& tp, std::index_sequence<Is...>) {
    ( f(std::get<Is>(tp)), ...);
}
 
class Formatter{
   
};
 
template<class CharT>
class Converter{
public:
   using StringType = std::basic_string<CharT>;
   
   template<class T>
   StringType operator()(const T& value) const{
      ss.str({});
      ss.clear();
      ss << value;
      return ss.str();
   }
   template<class T>   
   StringType operator()(const T& value, const Formatter& fmt) const{
      ss.str({});
      ss.clear();
      ss << value;
      return ss.str();
   }
   StringType endl(){
      ss.str({});
      ss.clear();
      ss << std::endl;
      return ss.str();
   }
   operator bool(){
      return bool(ss);
   }
protected:
   mutable std::basic_stringstream<CharT> ss;
};
 
struct DataPadding{
   unsigned left{1}, right{1}, top{0}, bottom {0};
};
   
struct Column{
public:
   // enum class Type {Fixed, Stretch};
   enum class Align {Right, Middle, Left};
   // enum class VAlign {Right, Middle, Left};
 
   // if width = 0, Type is Stretch 
   Column(unsigned width = 0, Align align = Align::Left/*, DataPadding padding = DataPadding{}*/)
      : align{align}/*, padding{padding}*/,  width{width}{
         
   }
 
   Align align;
   // DataPadding padding;
   unsigned width;
};
 
template<class CharT>
struct Decorator{
   // 11 символов рамок + заполнитель при выравнивании (обычно пробел)
   //  example 1 : L"│─┌┐└┘├┤┬┴┼ "
   //  example 2 : L"*********** "
   //  example 2 : L"|           " // vertical border only
   Decorator(const CharT* pack) 
      : pack{pack}{
      // if (pack.size < 12)
         // throw std::invalid_argument("Decorator() : must be at least 12 symbols");
      if (this->pack.size() < 12)
         this->pack = std::basic_string<CharT>(12, ' ');
   }
   CharT VBorder(){return pack[0];}
   CharT HBorder(){return pack[1];}
   
   CharT LTAngle(){return pack[2];}
   CharT RTAngle(){return pack[3];}
   CharT LBAngle(){return pack[4];}
   CharT RBAngle(){return pack[5];}
   
   CharT LCross(){return pack[6];}
   CharT RCross(){return pack[7];}
   CharT TCross(){return pack[9];}
   CharT BCross(){return pack[10];}
   CharT Cross(){return pack[8];}
   
   CharT Space(){return pack[11];}
protected:
   std::basic_string<CharT> pack;
};
 
template<class CharT, class... ColumnTypesT>
class BasicTable{
public:
   using RowTuple = std::tuple<ColumnTypesT...>;
   using StringType   = std::basic_string<CharT>;
   BasicTable(Decorator<CharT> decor) : decor{decor}{
   }
   void AddRowData(const RowTuple& data_row){
      // львиная доля расчетов будет при добавлении данных 
      std::vector<StringType> row;
      
      auto f = [&](auto&& val){
         row.emplace_back(conv(val));
      };
      
      apply(f, data_row, std::make_index_sequence<std::tuple_size<RowTuple>::value>());
 
      // if( conv )
      data.emplace_back(std::move(row));
      // else ...
   }
   
   template<class... Args>
   void AddRowValues(Args&&... args){
      AddRowData(std::make_tuple<Args...>(std::forward<Args>(args)...));
   }
   
   BasicTable& operator>>(std::basic_ostream<CharT>& out){
      for(size_t r = 0; r != data.size(); ++r){
         for(size_t c = 0; c != data[r].size(); ++c){
            if(columns[c].width < data[r][c].size())
               columns[c].width = data[r][c].size();
         }
      }
      CharT space = decor.Space();
      // make top border
 
      // out data
 
      for(size_t r = 0; r != data.size(); ++r){
         out << decor.VBorder();
         for(size_t c = 0; c != data[r].size(); ++c){
            out << space;
            switch(columns[c].align){
               case Column::Align::Left   : out << std::left; break;
               case Column::Align::Right  : out << std::right; break;
               case Column::Align::Middle   : out << std::internal; break;
            }
 
            out << std::left << std::setw(columns[c].width) << data[r][c];
            out << space;  
            out << decor.VBorder();
         }
 
         out << endl;
      }
      
      // make bottom border
      return *this;
   }
   
private:
 
protected:
   Decorator<CharT> decor;
   std::array<Column, std::tuple_size<RowTuple>::value> columns;
   std::vector<std::vector<StringType>> data;
   Converter<CharT> conv;
   StringType endl {conv.endl()};
   
};
 
}
 
int main(){
   setlocale(LC_ALL, "en_US.utf-8");
   Table::BasicTable<wchar_t, int, std::wstring, double> simple_table(Table::Decorator<wchar_t>(L"|           "));
   simple_table.AddRowValues(1, L"Первый", 1);
   simple_table.AddRowValues(2, L"Второй", 2.0);
   simple_table.AddRowValues(3, L"Третий10505054", 1.5f);
   simple_table >> std::wcout;
}


Добавлено через 3 минуты
p.s. С кортежами почти не работал, тем более шаблонно, на данный момент могут быть косяки и/или дополнительное копирование.
0
-46 / 3 / 0
Регистрация: 17.12.2011
Сообщений: 608
09.10.2025, 20:50  [ТС]
Подскажите, пожалуйста, почему возникли эти ошибки, и как их исправить?:
Tab::m: невозможно обратиться к private член, объявленному в классе "Tab"
Tab::h: невозможно обратиться к private член, объявленному в классе "Tab"
Tab::CMAX: невозможно обратиться к private член, объявленному в классе "Tab"


Еще вот такое предупреждение:
Не найдено определение функции для "operator<<".

h-file:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#pragma once
 
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <locale>
 
namespace school {
 
    // Класс-обертка для преобразования в строку
    class StringConverter
    {
    public:
        template<typename T>
        static std::wstring toString(T val)
        {
            return (std::wostringstream() << val).str();
        }
    };
 
    // Класс для работы со строками
    class MyString : public std::wstring
    {
    public:
        MyString();
        MyString(std::wstring s);
        MyString(const wchar_t* s);
 
        MyString& operator=(const std::wstring& a);
 
        template<typename T>
        MyString& operator=(const T a)
        {
            return *this = StringConverter::toString(a);
        }
    };
 
    // Класс для работы с вектором
    template<typename T>
    class MyVector : public std::vector<T>
    {
    public:
        T& operator[](const size_t i);
        void resize(size_t new_size, const T& value = T());
    };
 
    // Класс для форматирования таблицы
    class TableFormatter
    {
    private:
        MyVector<MyVector<MyString>>& m;
        MyVector<MyString>& h;
        size_t& CMAX;
 
    public:
        TableFormatter(size_t& cmax,
            MyVector<MyVector<MyString>>& data,
            MyVector<MyString>& header);
 
        void format();
 
    private:
        void calculateMaxColumns();
        void resizeRows();
        void addRowNumbers();
        void calculateColumnWidths();
        void alignColumns();
        void alignHeaders();
    };
 
    // Класс для вывода таблицы
    class TablePrinter
    {
    private:
        MyVector<MyVector<MyString>>& m;
        MyVector<MyString>& h;
        size_t& CMAX;
 
    public:
        TablePrinter(
            size_t& cmax,
            MyVector<MyVector<MyString>>& data,
            MyVector<MyString>& header);
 
        void print(std::wostream& o);
 
    private:
        std::wstring createLine();
        void printHeader(std::wostream& o);
        void printRows(std::wostream& o);
    };
 
    // Основной класс таблицы
    class Tab
    {
    private:
        MyVector<MyVector<MyString>> m;
        MyVector<MyString> h;
        size_t CMAX = 0;
 
    public:
        Tab();
 
        MyVector<MyString>& operator[](const size_t i);
 
        template<typename ... T>
        void head(T ... t)
        {
            (h.push_back(StringConverter::toString(t)), ...);
        }
 
        void formater();
 
        friend std::wostream& operator<<(std::wostream& o, Tab& t);
    };
 
    // Объявление дружественной функции
    std::wostream& operator<<(std::wostream& o, Tab& t);
 
    // Класс для тестирования
    class TabTest
    {
    public:
        void run();
    };
 
} // namespace school
cpp-file:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#include "DataTable.h"
 
 
 
#define l(v) std::wcout << #v << " = " << (v) << "\n";
 
// Класс-обертка для преобразования в строку
class StringConverter
{
public:
    template<typename T>
    static std::wstring toString(T val)
    {
        return (std::wostringstream() << val).str();
    }
};
 
 
// Класс для работы со строками
class MyString : public std::wstring
{
public:
    MyString() : std::wstring() {}
    MyString(std::wstring    s) : std::wstring(s) {}
    MyString(const wchar_t* s) : std::wstring(s) {}
 
    MyString& operator=(const std::wstring& a)
    {
        return   *static_cast<std::wstring*>(this) = a, *this;
    }
 
    template<typename T>
    MyString& operator=(const T a)
    {
        return *this = StringConverter::toString(a);
    }
};
 
 
// Класс для работы с вектором
template<typename T>
class MyVector : public std::vector<T>
{
public:
    T& operator[](const size_t i)
    {
        if (i >= this->size()) this->resize(i + 1);
        return *(this->begin() + i);
    }
 
    void resize(size_t new_size, const T& value = T())
    {
        std::vector<T>::resize(new_size, value);
    }
};
 
 
// Класс для форматирования таблицы
class TableFormatter
{
private:
    MyVector<MyVector<MyString>>& m;
    MyVector<MyString>& h;
    size_t& CMAX;
 
public:
    TableFormatter(size_t& cmax,
        MyVector<MyVector<MyString>>& data,
        MyVector<MyString>& header)
        : m(data), h(header), CMAX(cmax)
    {
    }
 
    void format()
    {
        calculateMaxColumns();
        resizeRows();
        addRowNumbers();
        calculateColumnWidths();
        alignColumns();
        alignHeaders();
    }
 
private:
    void calculateMaxColumns()
    {
        for (const auto& e : m)
            if (CMAX < e.size())
                CMAX = e.size();
    }
 
    void resizeRows()
    {
        for (auto& e : m)
            if (CMAX > e.size()) e.resize(CMAX);
 
        if (CMAX > h.size()) h.resize(CMAX);
    }
 
    void addRowNumbers()
    {
        for (size_t r = 0; r < m.size(); ++r)
        {
            m[r][0] = StringConverter::toString(r + 1);
        }
    }
 
    void calculateColumnWidths()
    {
        std::vector<size_t> n(CMAX, 0);
 
        // Инициализация ширинами заголовков
        for (size_t i = 0; i < h.size() && i < CMAX; ++i)
        {
            n[i] = h[i].size();
        }
 
        // Нахождение максимальных ширин
        for (size_t c = 0; c < CMAX; ++c)
        {
            for (size_t r = 0; r < m.size(); ++r)
            {
                if (n[c] < m[r][c].size())
                    n[c] = m[r][c].size();
            }
        }
 
        // Выравнивание столбцов
        for (size_t c = 0; c < CMAX; ++c)
        {
            for (size_t r = 0; r < m.size(); ++r)
            {
                if (n[c] > m[r][c].size())
                    m[r][c].resize(n[c], ' ');
            }
        }
 
        // Выравнивание заголовков
        for (size_t c = 0; c < CMAX; ++c)
        {
            if (h[c].size() < m[0][c].size())
                h[c].resize(m[0][c].size(), ' ');
        }
    }
 
    void alignColumns() {} // Заглушка для совместимости с логикой
    void alignHeaders() {} // Заглушка для совместимости с логикой
};
 
 
// Класс для вывода таблицы
class TablePrinter
{
private:
    MyVector<MyVector<MyString>>& m;
    MyVector<MyString>& h;
    size_t& CMAX;
 
public:
    TablePrinter(
        size_t& cmax,
        MyVector<MyVector<MyString>>& data,
        MyVector<MyString>& header)
        : CMAX(cmax), m(data), h(header)
    {
    }
 
    void print(std::wostream& o)
    {
        std::wstring line = createLine();
 
        o << line << '\n';
        printHeader(o);
        o << '\n' << line << '\n';
        printRows(o);
        o << line << '\n' << '\n';
    }
 
private:
    std::wstring createLine()
    {
        std::wstring line;
        for (size_t c = 0; c < CMAX; ++c)
        {
            line += std::wstring(h[c].size() + 3, '=');
        }
        return line;
    }
 
    void printHeader(std::wostream& o)
    {
        for (size_t c = 0; c < CMAX; ++c)
        {
            o << ' ' << h[c] << " |";
        }
    }
 
    void printRows(std::wostream& o)
    {
        for (const auto& r : m)
        {
            for (const auto& e : r)
            {
                o << ' ' << e << " |";
            }   o << '\n';
        }
    }
};
 
// Основной класс таблицы
class Tab
{
private:
    MyVector<MyVector<MyString>> m;
    MyVector<MyString> h;
    size_t CMAX = 0;
 
public:
    Tab() = default;
 
    MyVector<MyString>& operator[](const size_t i)
    {
        if (i >= m.size()) m.resize(i + 1);
        return *(m.begin() + i);
    }
 
    template<typename ... T>
    void head(T ... t)
    {
        (h.push_back(StringConverter::toString(t)), ...);
    }
 
    void formater()
    {
        TableFormatter formatter(CMAX, m, h);
        formatter.format();
    }
 
    friend std::wostream& operator<<(std::wostream&, Tab&);
};
 
std::wostream& operator<<(std::wostream& o, Tab& t)
{
    t.formater();
 
    TablePrinter printer(t.CMAX, t.m, t.h);
    printer.print(o);
 
    return o;
}
 
///----------------------------------------------------------------------------|
/// Тест.
///----------------------------------------------------------------------------:
class TabTest
{
public:
    void run()
    {   ///-----------------------|
        /// Создаём табулятор.    |
        ///-----------------------:
        Tab tab;
 
        ///-----------------------|
        /// Заголовок.            |
        ///-----------------------:
        tab.head(L"NN", L"Первый", L"Второй", 3);
 
        ///-----------------------|
        /// Как угодно заполняем. |
        ///-----------------------:
        tab[1][1] = 2020;
        tab[2][2] = "qwerty";
        tab[4][3] = 3.14;
        tab[0][4] = L"Яша + Оля";
 
        ///-----------------------|
        /// Вывод на экран/файл.  |
        ///-----------------------:
        std::wcout << tab;
 
        tab[2][4] = 2025;
        tab[3][5] = 'A';
 
        std::wcout << tab;
    }
};
0
-46 / 3 / 0
Регистрация: 17.12.2011
Сообщений: 608
15.10.2025, 16:00  [ТС]
Подскажите, пожалуйста, почему в место значения поля name выводится значения поля id?
PowerShell
1
2
3
4
5
6
7
8
9
Подключение установлено успешно!
 
Результаты на экране:
===================
 name | sex | age |
===================
 1    | ??  | 40  |
 2    | ??  | 75  |
===================
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#include "MySQLConnection.h"
 
#include <memory>
#include <mysql_driver.h>
#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
 
// библиотеки для создания таблтци
 
 
namespace school
{
    // ================================================= Класс для работы таблицы =====================================================
    // Реализация методов MyString
    MyString::MyString() : std::wstring() {}
 
    MyString::MyString(std::wstring s) : std::wstring(s) {}
 
    MyString::MyString(const wchar_t* s) : std::wstring(s) {}
 
    // Явная инстанциация шаблонов
    template class MyVector<MyString>;
    template class MyVector<MyVector<MyString>>;
 
    // Реализация TableFormatter
    TableFormatter::TableFormatter(size_t& cmax,
        MyVector<MyVector<MyString>>& data,
        MyVector<MyString>& header)
        : m(data), h(header), CMAX(cmax)
    {
    }
 
    void TableFormatter::format()
    {
        calculateMaxColumns();
        resizeRows();
        addRowNumbers();
        calculateColumnWidths();
        alignColumns();
        alignHeaders();
    }
 
    void TableFormatter::calculateMaxColumns()
    {
        for (const auto& e : m)
            if (CMAX < e.size())
                CMAX = e.size();
    }
 
    void TableFormatter::resizeRows()
    {
        for (auto& e : m)
            if (CMAX > e.size()) e.resize(CMAX);
 
        if (CMAX > h.size()) h.resize(CMAX);
    }
 
    void TableFormatter::addRowNumbers()
    {
        for (size_t r = 0; r < m.size(); ++r)
        {
            m[r][0] = StringConverter::toString(r + 1);
        }
    }
 
    void TableFormatter::calculateColumnWidths()
    {
        std::vector<size_t> n(CMAX, 0);
 
        // Инициализация ширинами заголовков
        for (size_t i = 0; i < h.size() && i < CMAX; ++i)
        {
            n[i] = h[i].size();
        }
 
        // Нахождение максимальных ширин
        for (size_t c = 0; c < CMAX; ++c)
        {
            for (size_t r = 0; r < m.size(); ++r)
            {
                if (n[c] < m[r][c].size())
                    n[c] = m[r][c].size();
            }
        }
 
        // Выравнивание столбцов
        for (size_t c = 0; c < CMAX; ++c)
        {
            for (size_t r = 0; r < m.size(); ++r)
            {
                if (n[c] > m[r][c].size())
                    m[r][c].resize(n[c], ' ');
            }
        }
 
        // Выравнивание заголовков
        for (size_t c = 0; c < CMAX; ++c)
        {
            if (h[c].size() < m[0][c].size())
                h[c].resize(m[0][c].size(), ' ');
        }
    }
 
    void TableFormatter::alignColumns() {}
    void TableFormatter::alignHeaders() {}
 
    // Реализация TablePrinter
    TablePrinter::TablePrinter(
        size_t& cmax,
        MyVector<MyVector<MyString>>& data,
        MyVector<MyString>& header)
        : CMAX(cmax), m(data), h(header)
    {
    }
 
    void TablePrinter::print(std::wostream& o)
    {
        std::wstring line = createLine();
 
        o << line << '\n';
        printHeader(o);
        o << '\n' << line << '\n';
        printRows(o);
        o << line << '\n' << '\n';
    }
 
    std::wstring TablePrinter::createLine()
    {
        std::wstring line;
        for (size_t c = 0; c < CMAX; ++c)
        {
            line += std::wstring(h[c].size() + 3, '=');
        }
        return line;
    }
 
    void TablePrinter::printHeader(std::wostream& o)
    {
        for (size_t c = 0; c < CMAX; ++c)
        {
            o << ' ' << h[c] << " |";
        }
    }
 
    void TablePrinter::printRows(std::wostream& o)
    {
        for (const auto& r : m)
        {
            for (const auto& e : r)
            {
                o << ' ' << e << " |";
            }
            o << '\n';
        }
    }
 
    // Реализация Tab
    Tab::Tab() = default;
 
    MyVector<MyString>& Tab::operator[](const size_t i)
    {
        if (i >= m.size()) m.resize(i + 1);
        return *(m.begin() + i);
    }
 
    void Tab::formater()
    {
        TableFormatter formatter(CMAX, m, h);
        formatter.format();
    }
 
    // Реализация оператора вывода
    std::wostream& operator<<(std::wostream& o, Tab& t)
    {
        t.formater();
 
        TablePrinter printer(t.CMAX, t.m, t.h);
        printer.print(o);
 
        return o;
    }
 
    // Реализация TabTest
    
    Tab TabTest::createTabFromResultSet(std::unique_ptr<sql::ResultSet> res)
    {
        ///-----------------------|
        /// Создаём табулятор.    |
        ///-----------------------:
        Tab tab;
        if (!res) return tab;
 
        try
        {
            sql::ResultSetMetaData* meta = res->getMetaData();
            int columnCount = meta->getColumnCount();
            
            // Создаем заголовки
            for (int i = 1; i <= columnCount; i++)
            {
                std::string columnName = meta->getColumnName(i);
                std::wstring wColumnName(columnName.begin(), columnName.end());
                tab.head(wColumnName);
            }
            
            // Заполняем данными
            int row = 0;
            while (res->next())
            {
                for (int col = 1; col <= columnCount; col++)
                {
                    std::string value = res->getString(col);
                    std::wstring wValue(value.begin(), value.end());
                    tab[row][col - 1] = res->wasNull() ? L"NULL" : wValue;
                }
                row++;
            }
        }
        catch (const sql::SQLException& e)
        {
            std::wcout << L"Ошибка при создании таблицы: " << e.what() << std::endl;
        }
 
        return tab;
    };
 
 
 
 
 
// ========================================= Класс для работы с данными базы данных MySQL =========================================
    MySQLConnection::MySQLConnection(const std::string& host, int port,
        const std::string& user, const std::string& password,
        const std::string& database) {
 
        sql::mysql::MySQL_Driver* driver = sql::mysql::get_mysql_driver_instance();
        std::string connectionString = "tcp://" + host + ":" + std::to_string(port);
 
        connection.reset(driver->connect(connectionString, user, password));
        connection->setSchema(database);
    }
 
    void MySQLConnection::executeQuery(const std::string& query) {
        std::unique_ptr<sql::Statement> stmt(connection->createStatement());
        std::unique_ptr<sql::ResultSet> res(stmt->executeQuery(query));
         
        TabTest tabTest;
        Tab resultTab = tabTest.createTabFromResultSet(std::move(res));
         
        std::wcout << resultTab; // Вывести когда нужно
       // tabTest.run(std::move(res));
    }
 
    bool MySQLConnection::isConnected() {
        return connection.get() != nullptr && !connection->isClosed();
    }
}
Добавлено через 4 минуты
P.S.

Как выделить CMD, вместа PowerShell?
0
Нарушитель
4085 / 2974 / 813
Регистрация: 29.06.2020
Сообщений: 10,988
15.10.2025, 22:12
Цитата Сообщение от DDim1000 Посмотреть сообщение
Как выделить CMD, вместа PowerShell?
Если бы этот вопрос ещё кто-то на русский перевел...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.10.2025, 22:12
Помогаю со студенческими работами здесь

Структура: Вывод результата в табличном виде
Как сделать так, чтобы и результат выводил в виде таблицы? Помогите, пожалуйста #include...

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

Вывод массива структур в табличном виде
Вот код для каталог строительных материалов, но почему-то таблица странно смещается вправо, как...

Есть массив в виде табличных данных, как его поделить на отдельные элементы для дальнейшей работы?
Есть массив в виде табличных данных,как его поделить на отдельные элементы для работы дальше?строка...

Работа с табличными базами данных. Реализация функции сортировки.
Вот код моей программы. Необходимо реализовать функцию сортировки данных!!! //project.cpp - Lab....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

Новые блоги и статьи
И решил я переделать этот ноут в машину для распределенных вычислений
Programma_Boinc 09.11.2025
И решил я переделать этот ноут в машину для распределенных вычислений Всем привет. А вот мой компьютер, переделанный из ноутбука. Был у меня ноут асус 2011 года. Со временем корпус превратился. . .
Мысли в слух
kumehtar 07.11.2025
Заметил среди людей, что по-настоящему верная дружба бывает между теми, с кем нечего делить.
Новая зверюга
volvo 07.11.2025
Подарок на Хеллоуин, и теперь у нас кроме Tuxedo Cat есть еще и щенок далматинца: Хочу еще Симбу взять, очень нравится. . .
Инференс ML моделей в Java: TensorFlow, DL4J и DJL
Javaican 05.11.2025
Python захватил мир машинного обучения - это факт. Но когда дело доходит до продакшена, ситуация не так однозначна. Помню проект в крупном банке три года назад: команда data science натренировала. . .
Mapped types (отображённые типы) в TypeScript
Reangularity 03.11.2025
Mapped types работают как конвейер - берут существующую структуру и производят новую по заданным правилам. Меняют модификаторы свойств, трансформируют значения, фильтруют ключи. Один раз описал. . .
Адаптивная случайность в Unity: динамические вероятности для улучшения игрового дизайна
GameUnited 02.11.2025
Мой знакомый геймдизайнер потерял двадцать процентов активной аудитории за неделю. А виновником оказался обычный генератор псевдослучайных чисел. Казалось бы - добавил в карточную игру случайное. . .
Протоколы в Python
py-thonny 31.10.2025
Традиционная утиная типизация работает просто: попробовал вызвать метод, получилось - отлично, не получилось - упал с ошибкой в рантайме. Протоколы добавляют сюда проверку на этапе статического. . .
C++26: Read-copy-update (RCU)
bytestream 30.10.2025
Прошло почти двадцать лет с тех пор, как производители процессоров отказались от гонки мегагерц и перешли на многоядерность. И знаете что? Мы до сих пор спотыкаемся о те же грабли. Каждый раз, когда. . .
Изображения webp на старых x32 ОС Windows XP и Windows 7
Argus19 30.10.2025
Изображения webp на старых x32 ОС Windows XP и Windows 7 Чтобы решить задачу, использовал интернет: поисковики Google и Yandex, а также подсказки Deep Seek. Как оказалось, чтобы создать. . .
Passkey в ASP.NET Core identity
stackOverflow 29.10.2025
Пароли мертвы. Нет, серьезно - я повторяю это уже лет пять, но теперь впервые за это время чувствую, что это не просто красивые слова. В . NET 10 команда Microsoft внедрила поддержку Passkey прямо в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru