Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 1 / 4
Регистрация: 13.05.2013
Сообщений: 673

Исправить имеющийся вывод на вывод в виде таблицы

16.06.2022, 13:14. Показов 2463. Ответов 17

Студворк — интернет-сервис помощи студентам
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
snprintf(msgtemp2, sizeof(msgtemp2), "------------- BATTLE.ON.KG TOP-15 -------------");
message_send_text(c,message_type_error,c,msgtemp2);
 
            snprintf(msgtemp, sizeof(msgtemp), "    Account    |    Score    |    Games    ");
            message_send_text(c,message_type_info,c,msgtemp);
            counter = 1;
            snprintf(query,sizeof(query),"select uid, acct_username,score,games FROM BNET ORDER BY `score` DESC LIMIT 15 ");
            result = sql->query_res(query);
            while(Row = sql->fetch_row(result))
            {
            int acct_username = std::atoi( Row[1] );
            int Score = std::atoi( Row[2] );
            int games = std::atoi( Row[3] );
                char* d_marker;
if (Score >= 0)
    d_marker = "D-";
if (Score >= 399)
    d_marker = "D-";
if (Score >= 400)
    d_marker = "D-";
if (Score >= 899)
    d_marker = "D-";
if (Score >= 900)
    d_marker = "D";
if (Score >= 1999)
    d_marker = "D";
if (Score >= 2000)
    d_marker = "D+";
if (Score >= 2999)
    d_marker = "D+";
if (Score >= 3000)
    d_marker = "C-";
if (Score >= 3999)
    d_marker = "C-";
if (Score >= 4000)
    d_marker = "C";
if (Score >= 4999)
    d_marker = "C";
if (Score >= 5000)
    d_marker = "C+";
if (Score >= 5999)
    d_marker = "C+";
if (Score >= 6000)
    d_marker = "B-";
if (Score >= 6999)
    d_marker = "B-";
if (Score >= 7000)
    d_marker = "B";
if (Score >= 7999)
    d_marker = "B";
if (Score >= 8000)
    d_marker = "B+";
if (Score >= 8999)
    d_marker = "B+";
if (Score >= 9000)
    d_marker = "A-";
if (Score >= 10499)
    d_marker = "A-";
if (Score >= 10500)
    d_marker = "A";
if (Score >= 11999)
    d_marker = "A";
if (Score >= 12000)
    d_marker = "A+";
if (Score >= 14999)
    d_marker = "A+";
if (Score >= 15000)
    d_marker = "A+";
if (Score >= 20000)
    d_marker = "A+";
            //int uid = std::atoi( Row[0] );
            snprintf(msgtemp, sizeof(msgtemp), "    %s    |    [%s] %s pts    |    %s " ,Row[1],d_marker,Row[2],Row[3]);
            message_send_text(c,message_type_info,c,msgtemp);
как можно этот код преобразовать и вывести в виде таблицы типа так

чтобы был типа так Accout | Score | Games
Миниатюры
Исправить имеющийся вывод на вывод в виде таблицы  
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.06.2022, 13:14
Ответы с готовыми решениями:

Как наложить свой текст на имеющийся граф.файл в VC++ 6.0
Посоветуйте пожалуйста, как можно наложить на уже имеющийся граф. файл ( BMP, GIF, JPG etc ) свой...

Создать линейный список по уже имеющийся структуре "Записная книжка"
У меня довольно таки сложная последняя лабораторная.(для меня, по крайней мере) Нужно создать...

Из dbedit в шаблон word. Сократить имеющийся код
Есть код, который выводит из DBEdit-ов информацию в заготовленный шаблон Word. void __fastcall...

17
Just Do It!
 Аватар для XLAT
4188 / 2642 / 654
Регистрация: 23.09.2014
Сообщений: 8,841
Записей в блоге: 3
17.06.2022, 01:15
Цитата Сообщение от esenbek Посмотреть сообщение
как можно этот код преобразовать и вывести в виде таблицы типа так
универсальный табулятор:
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
///----------------------------------------------------------------------------|
/// Пример использования.
///----------------------------------------------------------------------------:
void testclass_Tab()
{   ///-----------------------|
    /// Создаём табулятор.    |
    ///-----------------------:
    Tab tab;
 
    ///-----------------------|
    /// Заголовок.            |
    ///-----------------------:
        tab.head("NN", "Первый", "Второй", 3);
 
    ///-----------------------|
    /// Как угодно заполняем. |
    ///-----------------------:
        tab[1][1] = 2020;
        tab[2][2] = "qwerty";
        tab[4][3] = 3.14;
        tab[0][4] = "Яша + Оля";
 
    ///-----------------------|
    /// Вывод на экран/файл.  |
    ///-----------------------:
    std::cout << tab;
    std::cout << tab;
}
 
///----------------------------------------------------------------------------|
/// Старт.
///----------------------------------------------------------------------------:
int main()
{
    setlocale(0,"");
    testclass_Tab();
}
Полный кот
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
///----------------------------------------------------------------------------|
/// C++17
/// Табулятор.
///----------------------------------------------------------------------------:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
 
#define  l(v) std::cout << #v << " = " << (v) << "\n";
 
namespace std
{   template<typename T>
    T& to_string(T& s)
    {   return s;
    }
}
 
struct String : public std::string
{
    String(             )                  {}
    String(std::string s) : std::string(s) {}
 
    template<typename T> String operator=(const T a)
    {   *this = toString(a);
        return *this;
    }
 
    template<typename T> static String toString(T val)
    {   std::ostringstream oss;
                           oss << val;
        return             oss.str();
    }
};
 
template<typename T>
struct Vector : public std::vector<T>
{
    T& operator[](const size_t i)
    {
        if(i  >= this->size()) this->resize(i + 1);
        return *(this->begin() + i);
    }
};
 
struct  Tab
{       Tab()
        {
        }
 
    Vector<String>& 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(String::toString(t)), ...);
    }
 
private:
    Vector<Vector<String>> m;
    Vector<String>         h;
    size_t CMAX = 0;
 
    void formater()
    {   for(const auto& e : m) if(CMAX < e.size()) CMAX = e.size();
        for(      auto& e : m) if(CMAX > e.size()) e.resize (CMAX);
 
        if(CMAX > h.size()) h.resize (CMAX);
 
        for(size_t r = 0; r < m.size(); ++r)
        {   m[r][0] = std::to_string(r  + 1);
        }
 
        std::vector<size_t> n(CMAX,  0);
        {   size_t i = 0;
            for(auto& c : n) {c = h[i].size(); i++; }
        }
 
        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(), ' ');
        }
    }
 
    friend std::ostream& operator<<(std::ostream&, Tab&);
};
 
std::ostream& operator<<(std::ostream& o, Tab& t)
{
    t.formater();
 
    std::string line;
    for(size_t c = 0; c < t.CMAX; ++c)
    {   line += std::string(t.h[c].size() + 3, '=');
    }
 
    o << line << '\n';
    for(size_t c = 0; c < t.CMAX; ++c)
    {   o << ' ' << t.h[c] << " |";
    }
    o << '\n' << line << '\n';
 
    for    (const auto& r : t.m)
    {   for(const auto& e : r)
        {   o << ' ' << e << " |";
        }   o << '\n';
    }       o << '\n';
 
    return o;
}
 
///----------------------------------------------------------------------------|
/// Тест.
///----------------------------------------------------------------------------:
void testclass_Tab()
{   ///-----------------------|
    /// Создаём табулятор.    |
    ///-----------------------:
    Tab tab;
 
    ///-----------------------|
    /// Заголовок.            |
    ///-----------------------:
        tab.head("NN", "Первый", "Второй", 3);
 
    ///-----------------------|
    /// Как угодно заполняем. |
    ///-----------------------:
        tab[1][1] = 2020;
        tab[2][2] = "qwerty";
        tab[4][3] = 3.14;
        tab[0][4] = "Яша + Оля";
 
    ///-----------------------|
    /// Вывод на экран/файл.  |
    ///-----------------------:
    std::cout << tab;
    std::cout << tab;
}
 
///----------------------------------------------------------------------------|
/// Старт.
///----------------------------------------------------------------------------:
int main()
{
    setlocale(0,"");
    testclass_Tab();
}


рез:
1
Just Do It!
 Аватар для XLAT
4188 / 2642 / 654
Регистрация: 23.09.2014
Сообщений: 8,841
Записей в блоге: 3
18.06.2022, 12:51
шоп корректно в онлайн тулзах отображалось перевёл в utf-8:
0
-46 / 3 / 0
Регистрация: 17.12.2011
Сообщений: 609
07.10.2025, 14:39
Почему-то в терменал ничего не выводится, кроме этой сткроки:

Bash
1
2
D:\Programming\VS\source\repos\Test\x64\Debug\Test.exe (процесс 28480) завершил работу с кодом -1073741571 (0xc00000fd).
Нажмите любую клавишу, чтобы закрыть это окно:
Подскажите, пожалуйста, что ни так я сделал?

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
Just Do It!
 Аватар для XLAT
4188 / 2642 / 654
Регистрация: 23.09.2014
Сообщений: 8,841
Записей в блоге: 3
07.10.2025, 15:48
Цитата Сообщение от DDim1000 Посмотреть сообщение
Подскажите, пожалуйста, что ни так я сделал?
у вас Windows 7?

консоль от разных виндосов работает по разному.

у мя Windows 11
- создал прожект в VS 2022
- скопировал код отсюда
- поставил флажок на стандарт C++17
- во вкладке Debug --> Start Without Debugging
- рез норм:
0
 Аватар для Annemesski
2670 / 1333 / 479
Регистрация: 08.11.2016
Сообщений: 3,679
07.10.2025, 15:53
Цитата Сообщение от DDim1000 Посмотреть сообщение
что ни так я сделал?
Это не ты, это XLAT, вызвал бесконечную рекурсию в перегрузке оператора присваивания MyString
C++
29
30
31
32
33
34
template<typename T>
MyString& operator=(const T a)
{
    *this = StringConverter::toString(a);
    return *this;
}
вот этот вот *this = StringConverter::toString(a); заставляет программу вновь и вновь вызывать оператор присваивания MyString.Фиксится, например, так:
C++
1
2
3
4
5
6
template<typename T>
MyString& operator=(const T a)
{
    *static_cast<std::wstring *>(this) = StringConverter::toString(a);
    return *this;
}
1
Заблокирован
07.10.2025, 17:02
Цитата Сообщение от Annemesski Посмотреть сообщение
Это не ты, это XLAT
У него(XLAT) такого нет в коде.
Будь внимательней.
Ответ я уже дал в другой его теме этого автора.
И эта рекурсия, может быть не единственной ошибкой.
1
Just Do It!
 Аватар для XLAT
4188 / 2642 / 654
Регистрация: 23.09.2014
Сообщений: 8,841
Записей в блоге: 3
07.10.2025, 17:43
Цитата Сообщение от SmallEvil Посмотреть сообщение
такого нет в коде
верно.

но ок.
исправить такую хрень у автора просто:
C++
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Класс для работы со строками
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)
    {   *this = StringConverter::toString(a);
        return *this;
    }
};
далее, я вижу, что пропало отображение заголовка,
но я думаю автор сам разберется что он хочет и для чего он делает...

но на рандомной оси не факт, что всё будет работать корректно
по причине упомянутой мною тут.

виндовая консоль это трешак по совместимости кодировок в разных виндозах и так чтобы и в линуксах работало.

так что баг с рекурсией это мелкая мелочь...
0
Заблокирован
07.10.2025, 18:14
Цитата Сообщение от XLAT Посмотреть сообщение
но я думаю автор сам разберется что он хочет и для чего он делает...
Нууу....
Он впервые познакомился с кодировками, при этом со всеми(windows-1251, utf8, теперь ещё и широкие строки UTF16/32) сразу.
Как говорится: "в омут с головой". Но стремление похвальное.
1
 Аватар для Annemesski
2670 / 1333 / 479
Регистрация: 08.11.2016
Сообщений: 3,679
07.10.2025, 18:32
Цитата Сообщение от SmallEvil Посмотреть сообщение
У него(XLAT) такого нет в коде.
Цитата Сообщение от XLAT Посмотреть сообщение
верно.
сори, подумал DDim1000 тупо спастил твой кот (под спойлер не заглядывал).
1
-46 / 3 / 0
Регистрация: 17.12.2011
Сообщений: 609
07.10.2025, 19:16
Помогите, пожаплуста, как вид моей таблици: https://www.online-cpp.com/XHXSje0DdL привести к такому виду: https://rextester.com/GMWGS22837. Почему-то не выводятся загаловки...
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
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;
    }
};
0
Just Do It!
 Аватар для XLAT
4188 / 2642 / 654
Регистрация: 23.09.2014
Сообщений: 8,841
Записей в блоге: 3
08.10.2025, 01:15
Цитата Сообщение от DDim1000 Посмотреть сообщение
Помогите,
это случилось потому что вы перестали контролировать сложность своего кода)

Цитата Сообщение от DDim1000 Посмотреть сообщение
Почему-то не выводятся загаловки...
1. узнать что содержит заголовок.
2. проверить его размер во время вывода.
3. убедиться что размер его равен 0, что есть баг.
4. узнать причину его нуля.
5. причина его нуля в классе который принимает его по значению.
6. при этом целевой размер не модифицируется.
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
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
#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)
    {   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;
    }
};
 
///----------------------------------------------------------------------------|
/// Старт.
///----------------------------------------------------------------------------:
int main()
{   setlocale(0, "");
 
    TabTest test;
            test.run();
 
    return 0;
}
DDim1000,
вот вам скилл, как обмануть собственный моск:
- моск видит, что до вершины, как до Магадана раком.
- и отказывается идти...
- но вы заставляете его узнать, а можно ли сделать всего ОДИН ШАГ?
- ему некуда деваться и он отвечает ДА
- вы делаете этот шаг.
- гоуту выше на 3 позиции, пока не окажитесь на вершине.

это принцип декомпозиции в морально-волевом аспекте изложения.

НЕ ПЫТАЙТЕСЬ ДОСТИЧЬ КОНЕЧНОГО РЕЗУЛЬТАТ СРАЗУ - ДЛЯ НАЧАЛА
РЕШИТЕ ТОЛЬКО МАЛЕНЬКУЮ ЧАСТЬ ПРОБЛЕМЫ НА ПУТИ К РЕЗУЛЬТАТУ.
0
Заблокирован
08.10.2025, 22:50
XLAT, я не имею ничего против.
Но какой то костыльный слишком вариант.

Может сделаем толковую таблицу?
Пусть таскают её по форуму.

А что нужно, да чуток да и ещё немного.
Самое главное поставить четко задачу.

Задача: Создать инструмент формирования текстовой таблицы из любых данных приводимых в текст.

Требуемые возможности:
1. Оформление
- настраиваемое декоративное отображение таблицы, разделители строк/столбцов/пересечений/краев.
2. Верстка
- явное задание ширины и высоты каждого отдельного ряда/столбца и форматирование данных в нем.
- автоматическая подстройка ширины высоты в зависимости от данных, если явно не указаны размеры
- флаг для поведения в случае если данные не помещаются и соответственно поведение: обрезать данные/растягивать таблицу
3. Поддержка юникода.
4. Сами данные. Это один из ключевых моментов задачи.
Что же принимать и на каких условиях.
Я бы предпочел не работать с данными напрямую.
А получать при заполнении таблицы.
Что бы упростить(да и не вижу причин усложнять) работу с данными, предлагаю привязывать к столбцу тип данных.
При заполнении принимать лишь типы которые могут быть непосредственно преобразованы в указанный для столбца.

По первому этапу проектирования и декомпозиции всё.

Ничего сложного не предвидится.
Завтра сделаю первые наброски и демку.
0
Just Do It!
 Аватар для XLAT
4188 / 2642 / 654
Регистрация: 23.09.2014
Сообщений: 8,841
Записей в блоге: 3
09.10.2025, 10:22
Цитата Сообщение от SmallEvil Посмотреть сообщение
Может сделаем толковую таблицу?
- полно чуваков, которые могут сделать толковую таблицу.
- чуваков, которым эта таблица будет нужна, гораздо меньше.
- еще меньше тех чуваков, которые могут извлечь из этой таблицы 100'000'000 €.

и что?
а то, что выбирать надо третье)

Цитата Сообщение от SmallEvil Посмотреть сообщение
Но какой то костыльный слишком вариант.
Вариант автора выглядит как более костыльный, чем первоначальный,
потому что зачем оно такое понадобилось, знает только автор и только автор.
я допускаю, что цели автора учебные, тогда вариант автора есть норм.

Цитата Сообщение от SmallEvil Посмотреть сообщение
Самое главное поставить четко задачу.
какие овраги:

1.
понимание задачи кодера резко отличается от понимания задачи юзера, в плане того, юзера не интересуют детали техреза.

2.
техническое решение подменяет собой бизнес-цель, которая, кстати, полностью в настоящее время отсутствует.

3.
обратное от первого: кодер не знает, что в реальности нужно юзеру, рискуя(сильно) получить медведей на велосипеде.

4.
недооценка "человеческого фактора": идеальная с технической точки зрения система,
как правило пребывает в противоречии с эргономикой, UX-дизайном и тем, как люди реально работают...

итого, отдавать постанову задачи полностью реализатору идея провальная изначально))

т.е. необходима наличие юзера с задачей,
а уже апосля формулировать тех.часть в ТЗ док, сверяясь с хотелками юзера.
0
Заблокирован
09.10.2025, 11:01
Цитата Сообщение от SmallEvil Посмотреть сообщение
3. Поддержка юникода.
Юникод можно пока оставить в покое и ограничится только шаблонами и разными строками(мультибайтные, широкие).
Для поддержки юникода придется подключать стороннюю тяжеловесную либу, а текущую задачу можно решить хидеронли.
И такие таблицы будут актуальны только на моноширных шрифтах. Это должно быть понятно всем.

Цитата Сообщение от XLAT Посмотреть сообщение
т.е. необходима наличие юзера с задачей,
Есть юзер(DDim1000, ), есть задача:
Выводить данные полученные из БД в виде таблицы.
По его последним темам. Они очень последовательны(в разделе С++, в остальных ветках не проверял).

Добавлено через 1 минуту
Цитата Сообщение от XLAT Посмотреть сообщение
- еще меньше тех чуваков, которые могут извлечь из этой таблицы 100'000'000 €.
а то, что выбирать надо третье)
Ок, с тобой всё понятно. Вопросов и предложений больше не будет.
0
Заблокирован
09.10.2025, 20:42
XLAT, можешь идти глумится : Как вывести данные базы данных в табличном виде?
0
Эксперт функциональных языков программированияЭксперт С++
 Аватар для Royal_X
6092 / 2783 / 1037
Регистрация: 01.06.2021
Сообщений: 10,152
10.10.2025, 18:01
Цитата Сообщение от SmallEvil Посмотреть сообщение
Пусть таскают её по форуму.
Где-то я уже видел норм таблицу на форуме, но никак не найду (поиск бесполезен). В итоге и ваша таблица будет предана забвению. Ну или придется попросить, чтобы код добавили в "Важные темы".
Цитата Сообщение от XLAT Посмотреть сообщение
- еще меньше тех чуваков, которые могут извлечь из этой таблицы 100'000'000 €
молодец, что начал понимать, что мир держится на деньгах
0
Заблокирован
10.10.2025, 19:23
Цитата Сообщение от Royal_X Посмотреть сообщение
и ваша таблица будет предана забвению
Ничто не вечное. Где эти электронные табицы, ещё с ДОСа, которые в школах изучали.
Цитата Сообщение от Royal_X Посмотреть сообщение
что мир держится на деньгах
Это что, какой то секрет? [риторический вопрос]
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.10.2025, 19:23
Помогаю со студенческими работами здесь

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

Как запустить имеющийся код?
Как вставить скопированный текст в С++. Пожалуйста подскажите!

Как имеющийся список записать в файл или считать
Люди кто шарит хелп Нужно мою очередь как-то записать в файл или считать #define...

Организовать проверку на имеющийся файл для записи
Метод .open(), создает файл с вводимым именем, если такого нет в папке проекта, а как сделать чтобы...

Переписать имеющийся текстовый файл в обратном порядке
Здравствуйте.Нужна помощь,заранее спасибо Перепишите имеющийся текстовый файл в обратном порядке.


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru