На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (6) « Первая ... 3 4 [5] 6  все  ( Перейти к последнему сообщению )  
> Как исправить ошибку: "LNK2019 ссылка на неразрешенный внешний символ"?
    Цитата DDim1000 @


    Вы вкрячили непонятно что внутри namespace. Это и ни объявление функции, ни её реализация. Поэтому компилятор вас и не понял.
    system() или SetConsoleOutputCP() надо вызывать в main(). В добавок system() вам выдаст "мусор" в консоль "Active codepage xxxx", потому что это запуск команды cmd. Тогда уж system("chcp 65001 >nul").
    Сообщение отредактировано: sharky72 -
      Цитата Majestio @
      Просто ты не распознал всей вкусности юникода!
      Ещё как вкусил. Главная проблема юникода не в много...символьности (UTF-16 тоже имеет суррогатные пары). Главная его проблема в том, что вместо того, чтобы разобраться с зоопарком мультикультурности и устранить связанные с ним неудобства, он его стандартизировал и т.с. эти неудобства узаконил.
      Цитата Majestio @
      Да, пришли времена когда печатаемый символ может/должен занимать более одного байта
      Их никогда и не было. Но люди умели писать код в многобайтных кодировках. Проблема не в самой многобайтовости, а в отсутствии абстракции "символ". Это уже не к юникоду, конечно, а к std. Если уж ввели char8_t, префикс u8 и класс std::u8string, почему они по-прежнему отражают абстракцию "байт"?
      Мне несложно написать свои алгоритмы и функции для "символов" и таскать их из проекта в проект. Более того, в C++11 сделали некий шаг в эту сторону, предоставив фасеты и классы. Пусть шаг и неудобный, т.к. отделён от самой абстракции "символ", но вот прошло 6 лет, а воз не то что и ныне там, а этот шаг в принципе отменён, и ничего не предоставлено взамен. Причём формулировка причины, типа, "ой, мы ниасилили сделать это безопасно с точки зрения обработки апшибков" и "ай-яй-яй, эти фасеты локале-независимы, поэтому им нечего делать в <locale>". Оттакъот. Юникоду 35 лет, к слову, и <locale> появился аж в C++98, в первой редакции Стандарта.
      Сообщение отредактировано: Qraizer -
        Цитата DDim1000 @
        ExpandedWrap disabled
              system("chcp 65001");
        Не надо system(). Я ж упомянул программное средство:
        ExpandedWrap disabled
          SetConsoleOutputCP(65001);
          Здравствуйте!
          У меня снова возникла ошибка: "ссылка на неразрешенный внешний символ", другом проекте.
          ссылка на неразрешенный внешний символ "public: void __cdecl school::TabTest::run(void)" (?run@TabTest@school@@QEAAXXZ) в функции main.
          Еще такая ошибка:
          неразрешенных внешних элементов: 1

          h-file:
          ExpandedWrap disabled
            #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);
                };
             
                // Класс для работы со строками
                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);
                };
             
                // Класс для работы с вектором
                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);
                    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:
          ExpandedWrap disabled
            #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;
                }
            };


          source.cpp:
          ExpandedWrap disabled
            #include "DataTable.h"
             
            using namespace school;
             
            ///----------------------------------------------------------------------------|
            /// Старт.
            ///----------------------------------------------------------------------------:
            int main()
            {
                setlocale(0, "");
             
              TabTest test;
              test.run();
                
                return 0;
            }
            Ну так класс TabTest объявлен в пространстве имён school. Тот, что определён в глобальном, то другой, получается, они не совпадают.
              Цитата Qraizer @
              Ну так класс TabTest объявлен в пространстве имён school. Тот, что определён в глобальном, то другой, получается, они не совпадают.

              То есть, и заголовки и реализаци дожны находиться в одном прострастве имен?
                Я разместил код в прострастве имен school, и у меня вылезло куча ошибо. Почемиу?

                ExpandedWrap disabled
                  #include "DataTable.h"
                   
                   
                   
                  namespace school
                  {
                      #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;
                          }
                      };
                  };

                Прикреплённая картинка
                Прикреплённая картинка
                  Вам же Qraizer сказал.
                  Объявление и реализация должны быть в одном namespace.
                  в cpp файле так же должно быть указано
                  namespace school {
                  Тут должна быть вся реализация и объявления классов
                  }

                  Зы. Таки все объявления классов StringConverter, MyString, MyVector и т.д. я бы перенес в .h Выглядит очень некрасиво.
                  Сообщение отредактировано: sharky72 -
                    Цитата sharky72 @
                    Вам же Qraizer сказал.
                    Объявление и реализация должны быть в одном namespace.

                    А у меня разве не в одном namespace?
                      Цитата DDim1000 @
                      Цитата sharky72 @
                      Вам же Qraizer сказал.
                      Объявление и реализация должны быть в одном namespace.

                      А у меня разве не в одном namespace?

                      Неа. Я не вижу namespace school {) в cpp и внутри все что должно ему принадлежать

                      .h

                      ExpandedWrap disabled
                        namespace mynamespace
                        {
                          class classname
                          {
                             void method1();
                             void method2();
                          }
                         
                          void function();
                        }

                      .cpp

                      ExpandedWrap disabled
                        namespace mynamespace
                        {
                          void classname::method1(){}
                          void classname::method2(){}
                         
                          void function(){}
                        }
                      Сообщение отредактировано: sharky72 -
                        Цитата sharky72 @

                        Как так? А это что?":
                        ExpandedWrap disabled
                          namespace school
                          {
                           // ...
                          }

                        Прикреплённая картинка
                        Прикреплённая картинка
                          Так не нужно же дублировать определения. Отдельно, в .cpp, определять нужно только то, что в .h было только объявлено. (В свою очередь в .h определять нужно типы и inline, остальное должно быть только объявлено, а определено в .cpp)
                            Ну я же не вижу где находится ваш класс Tab и судя по ошибке его нет в данном namespace. Не говоря о том что по скрину MyString и MyVector, StringConverter определены как в .h так и в .cpp поэтому ошибка двойного определения С2011
                            Не надо выкладывать скрины. Либо выкладывайте проект, либо заворачивайте в /code. С телефона смотреть не всегда удобно, не говоря о том что скрин показывает только часть кода.

                            Как должны выглядеть объявление и реализация я вам написал.
                            Сообщение отредактировано: sharky72 -
                              Например, класс TabTest не содержит inline методов, поэтому определён правильно: метод TabTest::run() только объявлен. Но определение в .cpp должно быть только для метода:
                              ExpandedWrap disabled
                                namespace school
                                {
                                /* ... */
                                    ///----------------------------------------------------------------------------|
                                    /// Тест.
                                    ///----------------------------------------------------------------------------:
                                    void TabTest::run()
                                    {
                                /* ... */
                                    }
                                }
                              Потому что только он и остался не определённым.

                              Добавлено
                              P.S. Если ранее писал на Джаве (Шарпы, мэйби?), то в Плюсах так тоже можно, но не приветствуется. Только в отдельных случаях
                              Сообщение отредактировано: Qraizer -
                                Я так понял, что у меня пробле с загаловками? Потому что в одном файле все работает.

                                Source.cpp:
                                ExpandedWrap disabled
                                  #include <iostream>
                                  #include <sstream>
                                  #include <string>
                                  #include <vector>
                                  #include <locale>
                                   
                                   
                                  #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] = L"qwerty";
                                          tab[4][3] = 3.14;
                                          tab[0][4] = L"Яша + Оля";
                                   
                                          ///-----------------------|
                                          /// Вывод на экран/файл.  |
                                          ///-----------------------:
                                          std::wcout << tab;
                                   
                                          tab[2][4] = 2025;
                                          tab[3][5] = L'A';
                                   
                                          std::wcout << tab;
                                      }
                                  };
                                   
                                  ///----------------------------------------------------------------------------|
                                  /// Старт.
                                  ///----------------------------------------------------------------------------:
                                  int main()
                                  {
                                    setlocale(0, "ru");
                                   
                                    TabTest test;
                                    test.run();
                                      
                                      return 0;
                                  }
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0699 ]   [ 20 queries used ]   [ Generated: 23.10.25, 20:44 GMT ]