Ответы пользователя по тегу C++
  • Разработка под Windows - MSVC или TDM GCC (MinGW)?

    @Mercury13
    Программист на «си с крестами» и не только
    3) Использование инициализации списком для структур (POD) с уже прединициализированными полями:

    Это C++11. Хорошее дело. MinGW поддерживал, пока стандарт ещё вырабатывался. MSVC начал было, да бросил и довёл до конца аж в 2015!!

    1) Разное содержимое одних и тех же хедеров

    Не выбивается из стандарта.

    2) MSVC спокойно компилирует нечто вроде

    MSVC ошибается, таким образом неконстантную ссылку передавать запрещено.

    но при этом не компилирует код, если не-void функция не возвращает значение

    Хорошая диагностика, но это лишь warning, а не error. Компилятору трудно знать, возможен ли тот или иной путь исполнения кода.
    Ответ написан
    Комментировать
  • С++: Вызов различных конструкторов в зависимости от пользовательского ввода?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Свой код — сделать функцию init
    Foo foo;
    if (someFlag)
      foo.init("SomeString");
      else foo.init(42);

    2. Чужой код — сделать обёртку, которая в init будет использовать placement new, а в деструкторе — явно вызывать деструктор объекта.
    class FooWrap {
    public:
      FooWrap() : hasFoo(false) {}
      void init(int x) { new (fooPlace) Foo(x); hasFoo = true; }
      Foo& operator * () { return *reinterpret_cast<Foo*>(fooPlace); }
      Foo* operator -> () { return reinterpret_cast<Foo*>(fooPlace); }
      ~FooWrap() { if (hasFoo) (*this)->~Foo(); }
      // Да, и конструктор копирования и op= не забыть — оставлю как упражнение.
    private:
      char fooPlace[sizeof(Foo)];
      bool hasFoo;
    }
    
    FooWrap foo;
    if (someFlag)
      foo.init("SomeString");
      else foo.init(42);
    foo->doFoo();

    Для большей надёжности стоит указать, что FooWrap выравнивать как Foo — это делается через C++11 или расширениями компилятора.
    Ответ написан
    3 комментария
  • Как добавить динамическую библиотеку в проект напрямую?

    @Mercury13
    Программист на «си с крестами» и не только
    Задача lib — указать если не код функций, то хотя бы каким образом их прилинковывать из DLL. В частности, как «искозявлено» имя функции при переводе с Си на Си++. Этот самый lib — издержка разделения функций между компилятором и линкером.
    Не знаю, как MSVS/cl, но MinGW/ld с определённого момента начал прилинковывать DLL просто по наличию этого DLL, без построения *.a (а Embarcadero/ilink32, насколько мне известно, умел это изначально). С одной стороны, это серьёзно упрощает жизнь. С другой — для некоторых хитрых способов преобразования имён (или даже без имён, как в небезызвестном storm.dll) он не выцепит, что с чем слинковывать, *.a всё равно потребуется.
    stackoverflow.com/questions/31708832/how-to-refere...
    www.codeproject.com/Questions/613668/Is-it-possibl...
    Простейший, действующий на любом компиляторе способ — это сделать DLL-заглушку со всеми нужными нам функциями в нужных нам соглашениях вызова и с нужным образом закозявленными именами. Код может быть любым, хоть пустым. Компилируем, подставляем этот lib и правильный DLL.
    Второй способ — получить список имён функций, собрать их в *.def с правильными соответствиями «имя в коде — имя в DLL» и сделать из этого *.lib. Какими программами это делается в MSVS — описано по одной из ссылок.
    Ответ написан
    2 комментария
  • Динамический массив строк, используя string, в чем проблема?

    @Mercury13
    Программист на «си с крестами» и не только
    i++;
        a[2] = "monday";

    Выход за пределы массива. Массив длины 2 имеет два элемента: [0] и [1].
    Ответ написан
    Комментировать
  • Когда имеет значение порядок подключения заголовочных файлов?

    @Mercury13
    Программист на «си с крестами» и не только
    Заголовочные файлы надо писать так, чтобы порядок их подключения был неважен.

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

    Совать #include в пространство имён без хорошего обоснования не стоит.

    По вашему обтекаемому описанию не видно, как устроены ваши заголовки, именованное пространство имён или нет, закрыты ли все скобки в хедерах, и т.д. Но причина ошибки очевидна: из-за пространств имён компилятор не отождествил классы в первом и втором заголовке; предварительное объявление «class A;» осталось неразрешённым. Поэкспериментировав, я выяснил вот что.
    // Не компилируется!
    class A;
    
    namespace XXX {
        std::shared_ptr<A> a;
        class A { public: int x; };
        void xxx();
    }
    
    void XXX::xxx() {
        a->x;
    }


    // Компилируется!
    class A;
    
    namespace XXX {
        class A { public: int x; };
        std::shared_ptr<A> a;
        void xxx();
    }
    
    void XXX::xxx() {
        a->x;
    }

    // Тоже компилируется!
    namespace XXX {
        class A;
    }
    
    namespace XXX {
        std::shared_ptr<A> a;
        class A { public: int x; };
        void xxx();
    }
    
    void XXX::xxx() {
        a->x;
    }

    В первом случае shared_ptr<::A>, который, естественно, не определён (есть XXX::A).
    Во втором — определение наперёд ::A вообще ни на что не сдалось; используется shared_ptr<XXX::A>.
    В третьем примере только один тип, XXX::A.

    Если первым идёт не использование, а make_shared — выходит другая ошибка, не удаётся получить sizeof недоопределённого типа A.
    Ответ написан
    2 комментария
  • Код из Delphi в С++!?

    @Mercury13
    Программист на «си с крестами» и не только
    InStr/InSize — немного избыточно по дельфийским меркам и можно преобразоватть в const char* data / size_t length.

    Результат — ну std::string, разумеется. Или std::vector<char>. Что вместо SetLength — читай доку.

    InStr[i + 1] → data[i]. Остальные массивы нумеруются с нуля, всё как и было.

    Inc(j) → ++j.

    Мне кажется, этот код механически переписывался с Си на Паскаль и переписать обратно будет несложно.

    Ещё тут магическое число 16 — догадайся, на что заменять. Кстати, не стоит размазывать по коду две строки, связанные с j.
    Ответ написан
  • Как быть с реестром (пишет в WOW64)?

    @Mercury13
    Программист на «си с крестами» и не только
    Так надо, у W32 и W64 разные места в реестре. И в 90% случаев ничего не надо делать.
    Но иногда всё-таки приходится, например:
    • Есть проги для W32 и W64, и хотелось бы иметь общие настройки.
    • Прога для W32 читает чужие настройки от проги для W64, и наоборот.
    • У вас программа, оперирующая реестром: редактор, чистильщик, архиватор…
    Тогда вот дока от M$, объясняющая всё это.
    https://msdn.microsoft.com/en-us/library/windows/d...

    P.S. «Работает с реестром» — это пишет свои настройки в реестр или действительно оперирует реестром, типа редактора или чистильщика реестра?
    Ответ написан
    2 комментария
  • Стоит ли вынести объявление типов в отдельный файл?

    @Mercury13
    Программист на «си с крестами» и не только
    Стоит!
    Назовите этот хедер как-нибудь defines.h
    Ответ написан
    Комментировать
  • Как взять данные stringstream без копирования?

    @Mercury13
    Программист на «си с крестами» и не только
    stringstream не обязан хранить данные в строке. Так что функция str() просто собирает информацию в строку.

    https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++...

    Судя по исходникам G++, их sstream хранит информацию в длинном буфере, но не в строке. Но и это не обязательно; буферов может быть много.

    Так что, к сожалению, для экономии памяти придётся делать свой велосипед. Правда, как говорит MiiNiPaa, некоторые задачи удастся выполнить и на stringstream’е, воспользовавшись, например, итератором.
    Ответ написан
    Комментировать
  • Для чего нужны замыкания в C++ и как вы их используете?

    @Mercury13
    Программист на «си с крестами» и не только
    Замыкание — это способ передать в callback, из какого контекста он запустился.
    struct Row {
      int data[10];
    };
    struct Table {
      Row rows[10];
    }

    Нам нужно отсортировать таблицу по j-му столбцу. Номер j заранее неизвестен.

    int sortJ;
    
    int myCompare(const void* a,const void* b) {
      int ia = reinterpret_cast<Row*>(a)->data[sortJ];
      int ib = reinterpret_cast<Row*>(b)->data[sortJ];
      if (ia < ib) return -1;
      if (ia == ib) return 0;
      return 1;
    }
    
    int someJ = 5;
    sortJ = someJ;
    qsort(table.rows, 10, sizeof(Row), myCompare);

    Вот эта переменная sortJ — по какому столбцу сортировать — это и есть замыкание. Но, как известно, «избегай незнакомых женщин и глобальных переменных». Поэтому на STL мы делаем функтор (объект-функцию) и эту информацию кидаем в него.

    class MyCompare {
    public:
      MyCompare(int aJ) : j(aJ) {}
      bool operator () (const Row& a, const Row& b) const
        { return (a.data[j] < b.data[j]); }
    private:
      const int j;
    }
    
    int someJ = 5;
    std::sort(table.rows, table.rows + 10, MyCompare(someJ));

    Вот мы и избавились от глобальной переменной, закинув наше замыкание в private-поля объекта.

    Что плохо? Не будем говорить про технические тонкости. С точки зрения красоты и лаконичности кода: код слишком разлапистый. И тут пришёл C++11.
    int someJ = 5;
    std::sort(table.rows, table.rows + 10,
      [someJ](const Row& a, const Row& b) -> bool { return (a.data[someJ] < b.data[someJ]); } );

    Корявовато, но таков синтаксис Си++. Автоматически создаётся объект-функтор, и someJ становится его полем. Вот оно, замыкание — [someJ] — то есть те вещи, которые надо протащить внутрь функтора.

    Из реального проекта. Отбегал поток автоматического поиска нового регистрационного ключа; если что-то получилось — синхронно вызываем лямбду через Qt’шный механизм «сигнал-слот». Чтобы всё было синхронно, нужен объект, живущий в главном потоке (и он в интерфейсе MainControl — управление главной формой — тоже есть). Но тогда придётся вызывать не слот, а лямбду. Этой лямбде нужны два поля: fReregKey (новый ключ защиты от копирования) и fMainControl. Оба они в this, его и замыкаем.
    connect(this, &RenewThread::needUpdate, fMainControl.maincQobj(),
                [this]() {
            drm::createFile(fReregKey);
            fMainControl.maincLayoutOnRegister();
        });


    А теперь посмотрим в WinApi. Первая попавшаяся функция из DirectInput.
    HRESULT EnumObjects(
             LPDIENUMDEVICEOBJECTSCALLBACK lpCallback,
             LPVOID pvRef,
             DWORD dwFlags
    );
    
    BOOL DIEnumDeviceObjectsCallback(
             LPCDIDEVICEOBJECTINSTANCE lpddoi,
             LPVOID pvRef
    );

    Про pvRef говорится: функции EnumObjects он ни на что не нужен; что функция приняла, то и даст в callback. Тоже форма замыкания: можно передать указатель на любые данные, которые нужны callback’у.
    Ответ написан
    4 комментария
  • Почему ошибка в netbeans c++?

    @Mercury13
    Программист на «си с крестами» и не только
    В одном проекте два CPP-файла: int_float.cpp и hello.cpp. В обоих по main’у.
    Я не знаю, как NB объединяет файлы в проект, но если всё, что в каталоге и подкаталогах — значит, не держи где-то в подкаталогах другой проект.

    Второй вариант — очистить временный каталог с .o-файлами; там, возможно, завалялось что-то старое.
    Ответ написан
    Комментировать
  • Как разнести класс по файлам?

    @Mercury13
    Программист на «си с крестами» и не только
    Принцип прост. В .h можно ставить только то, что не производит кода. Как только в проекте появится второй CPP и задействует этот хедер, код будет произведён дважды, и компоновщик (cl/ld/ilink) будет ругаться, что переменная или функция в двух экземплярах. Что именно не производит кода…
    • Определения макросов. Они в принципе кода не производят.
    • Объявление любого типа. Оно лишь говорит об устройстве этого самого типа; код же производят те, кто этим типом пользуются.
    • Шаблоны. Код производит не сам шаблон, а факт расшаблонивания. Разумеется, шаблон может расшаблониться в двух единицах компиляции, но с этим автоматически бороться научились.
    • inline—  код производит не сам inline, а факт включения. inline бывает как явный ключевым словом, так и неявный — в теле класса.
    • Прототипы и extern — они говорят: код есть, но где-то не здесь.
    • Constexpr C++11. Они подставляют значение.
    • Некоторые const в зависимости от компилятора. Например, на Borland const double производит код, а const int — нет.

    Производят код и в хедерах запрещены.
    • Переменная без extern, даже const.
    • Функция, которая не inline.
    • Полностью специализированный шаблон, в котором не осталось шаблонных параметров (template<>).

    Не производят кода, но и лучше закинуть в CPP.
    • Некоторые скрытые (private) inline и шаблоны, если они не используются из хедера.
    Ответ написан
    3 комментария
  • Как правильно организовать структуру в классе?

    @Mercury13
    Программист на «си с крестами» и не только
    Помимо того, что я написал…

    1. Как устроить данные?
    struct CheckLine {
    public:
       int itemCode;    // код товара
       int qty;         // количество
       int price;       // цена, по которой всё это продано в копейках
       const CheckLine* next() const { return _next; }
    private:
       friend class Check;   // я тут ошибся с const-корректностью и заconst’ив всё, что можно, не дал Check’у писать
       CheckLine* _next;
    }
    
    class Check {
    public:
        Check() : _firstLine(NULL), _lastLine(NULL) {}
        void addLine(int itemCode, int qty, int price);   // пиши реализацию сам.
        const CheckLine* firstLine() const { return _firstLine; }
        ~Check();  // не забудь про деструктор…
        Check(const Check&)  // …конструктор копирования…
        Check& operator = (const Check&);  // и операцию «присвоить».
    private:
        CheckLine *_firstLine, *_lastLine;
    }

    В общем, я тут для простоты (мы же пока не знаем, что такое vector) наладил хранение данных связанным списком.

    2. Во внутренней кухне класса ты обращаешься к консоли. Зачем? Обычно это делают как можно ближе к main.

    Вернусь — буду писать дальше.
    Ответ написан
    3 комментария
  • Как объяснить кусок кода C++?

    @Mercury13
    Программист на «си с крестами» и не только
    Весь этот код (за исключением Close) — автогенерируемый.

    ///// Защита от повторного включения
    #ifndef Unit1H
    #define Unit1H
    
    ///// Хедеры VCL. Причём всё это сделано так, чтобы упростить написание ценой удлинения
    ///// компиляции. Более громоздкий, но и более удачный вариант.
    ///// В H:
    /////   namespace Controls { class TLabel; }
    /////   using namespace Controls;
    ///// В CPP:
    /////   #include <Controls.hpp>
    ///// Вот таким образом можно (было) избавиться от каскадного подключения
    ///// хедера Controls. А то каждый, кто использует главной форму,
    ///// автоматически подключает эти хедеры.
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    ///// Только от Forms.hpp избавиться таким макаром нельзя:
    ///// мы наследуемся от TForm.
    #include <Forms.hpp>
    
    ///// Класс формы. Все формы наследуются от TForm.
    class TForm1 : public TForm
    {
       ///// Особое право доступа Borland, для совместимости с Delphi.
       ///// Поля и свойства published не просто public, но включаются
       ///// в структуру рефлексии (aka reflection или introspection)
       ///// и программа о них знает при выполнении.
       ///// Применительно к формам — published-поля доступны
       ///// загрузчику.
    __published: // IDE-managed Components
       ///// Компоненты, которые мы установили на форме редактором.
    TLabel *Label1;
    TButton *Button1;
       ///// События, которые мы прописали в редакторе.
       ///// __fastcall — модель вызова, аналогичная Delphi.
       ///// Именно такая модель вызова принята в обработчиках
       ///// событий.
    void __fastcall Button1Click(TObject *Sender);
       ///// Пользователь пока не прописал никаких своих
       ///// полей и функций.
    private: // User declarations
    public: // User declarations
       ///// Конструктор. Раз уж у формы нетривиальный конструктор —
       ///// по правилам Си++ его надо повторить в подклассе.
       ///// Снова-таки, модель вызова __fastcall: в формах Delphi
       ///// используются т.н. виртуальные конструкторы, 
       ///// когда по имени класса можно создать объект этого класса.
       ///// Фабричный метод, только немного лучше.
       ///// Но это значит: у всех подчинённых классов
       ///// должен быть один и тот же набор параметров
       ///// и модель вызова.
    __fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    ///// Как известно, переменная объявляется один раз.
    ///// Поскольку хедер может подключаться к огромному числу CPP,
    ///// её объявляют как extern (она есть, но в другом месте).
    ///// Макрос PACKAGE раскрывается в __declspec(package),
    ///// чтобы эту штуку можно было собрать как пакет.
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif

    Модель вызова — это как технически мы вызываем подпрограмму. Какая память и какие регистры на это используются, и кто подчищает стек. Ищи в Википедии.
    Ответ написан
    Комментировать
  • Как в Linux через raw sockets подключиться к tcp-серверу, используя Qt?

    @Mercury13
    Программист на «си с крестами» и не только
    ::connect
    Ответ написан
    Комментировать
  • Почему не компилируется helloworld с использованием wxWidgets?

    @Mercury13
    Программист на «си с крестами» и не только
    Project → Build Options → Search Directories → Linker
    Ответ написан
  • Как посчитать сумму чисел в файле?

    @Mercury13
    Программист на «си с крестами» и не только
    Пока вижу вот что.
    1. a += buff[i]; Вы суммируете коды символов, а не их числовые значения. Правильно a += buff[i] - '0';

    2. Эти строки дублируют друг друга.
    fin >> buff;
      fin.getline(buff, 11);

    Сначала получаем 0123456789, потом файл кончился и на место 0 записываем нулевой символ (NUL).

    3. for (int i = 0; i < 11; i++) — неуниверсальная конструкция. Плюс цифр в строчке всего 10, поэтому надо i < 10.

    4. Так сумму чисел или сумму цифр?
    Ответ написан
  • Как реализовывается функцию(main), которая будет производить проверку?

    @Mercury13
    Программист на «си с крестами» и не только
    Мы пишем модульный тест собственными силами, без фреймворка. Это значит, что нам надо каким-то образом сымитировать работу фреймворка, но собственными силами и минимумом строчек.

    Для удобства нам потребуется одна функция — и немного препроцессорной магии.
    #include <iostream>
    #include <cstring>
    
    void doAssert(bool condition, int line)
    {
        if (condition) {
            std::cout << "Line " << line << " ok" << std::endl;
        } else {
            std::cout << "Line " << line << " FAILED" << std::endl;
        }
    }
    
    #define ASSERT(x) doAssert(x, __LINE__)
    #define ASSERT_STREQ(x, y) doAssert((std::strcmp(x, y) == 0), __LINE__)


    А теперь что-нибудь протестируем. Например, создание строки. Для простоты я проверю не вашу строку, а std::string.
    void testStringCreation()
    {
        std::string s;
        ASSERT(s.length() == 0);
        ASSERT(s.empty());
        ASSERT_STREQ("", s.c_str());
    }

    Проверим ещё операцию +=.
    void testPlusEq()
    {
        std::string s1 = "Alpha";
        std::string s2 = "Bravo";
        s1 += s2;
        ASSERT_STREQ("AlphaBravo", s1.c_str());
    }
    
    int main()
    {
        testStringCreation();
        testPlusEq();
        return 0;
    }

    Нужны ещё тесты — создавай новую функцию и вызывай её из main.
    Если какой-то тест не проходит — уничтожаем из main все вызовы, кроме несработавшего, и начинаем отладку.

    А теперь немного о том, какие должны быть модульные тесты.
    1. Изолированные. Если уничтожить часть тестов или запустить их в другом порядке, ничего не должно меняться — при условии, конечно, что никто не обращается к чужой памяти.
    2. Каждый модульный тест проверяет одну концепцию, которая указана в его названии. Например: строка создаётся, работает операция +=, и т.д. Будет очень много дублей кода, просто смиритесь с этим.
    3. Но нет ничего зазорного, что какой-то тест полагается на концепции, испытанные в других тестах. Если мы испытываем +=, то полагаем, что конструктор копирования работает, и не будем испытывать это.
    4. Модульным тестам иногда приходится иметь дело с внутренним поведением объекта. В таком случае объект должен выдавать наружу некоторую информацию — например, соответствующие функции обычно private, но по какой-то препроцессорной команде они становятся public.
    5. Модульные тесты обычно имеют дело с простейшим поведением объекта. Это не нагрузочные тесты, надо с этим просто смириться.
    6. Принцип работы теста таков. Создать исходные объекты, убедиться в том, что их ВНУТРЕННЕЕ (неспецифицированное, зависящее от реализации) состояние верное, провести некое действие, убедиться, что действие проведено правильно. Например, пусть строка выделяет память с запасом, и надо проверить, как она расширяется — тогда при присваивании "Alpha" мы убеждаемся, что выделено менее 10 символов, затем проводим s1 += "Bravo", затем убеждаемся, что выделено, например, 16 символов.
    7. Но заранее не нужно проверять, верно ли ВНЕШНЕЕ (заспецифицированное) состояние. Если мы пишем s1 = "Alpha", значит, строка равна "Alpha", и точка. Все случаи, возможные в операции string = char*, разумеется, покрыты другими тестами.
    8. Если вдруг в «боевом» коде обнаружится ошибка, надо сделать юнит-тест, её повторяющий, затем исправить ошибку и констатировать, что тест проходит и остальные тесты не «упали».
    9. То же самое, если ошибка случилась, когда проверяли другую концепцию. Проверяем +=, а глюк в конструкторе копирования — заводи новый тест, покрывающий эту ошибку.
    10. В проверках на равенство принят порядок ASSERT_EQ(что_должно_быть, что_реально_есть).
    Ответ написан
    Комментировать
  • На какой версии C++ Builder(максим. доступной) можно запустить проект C++ Builder 6?

    @Mercury13
    Программист на «си с крестами» и не только
    Переписывать придётся.

    1. Потому что в паскале — string и есть string, и раньше он был Ansi-, а теперь Unicode-. А на Си — именно что AnsiString/UnicodeString.
    2. То же самое касательно char. В Паскале-то можно объявить, что отныне char двухбайтовый, а на Си — есть стандарт, и по стандарту Си char — это один байт.
    3. Алгоритмы-то какие используются? Возможны какие-то алгоритмические уловки на манер алгоритма поиска подстроки Бойера-Мура — там тоже придётся переписывать.
    4. Если программа работает с файлами или сетью — надо указывать, как юникодные строки сериализовать. На Windows распространены UTF-16 Intel и UTF-8. На этот счёт AnsiString почти не используется в истинно юникодных программах из-за того, что хранит кодировку; если нужна цепочка байтов — есть RawByteString или std::string.
    5. Иногда старые программы работают с Юникодом через WideString (обёртку над BSTR). Сейчас этот WideString придётся массово менять на Unicode-.
    6. По-другому пишутся стандартные хедеры Delphi/VCL. Ранее #include <Forms.hpp>, сейчас — #include <Vcl.Forms.hpp>.

    Версия Builder — ну, любая, какую найдёшь. Не забудь только, что из C++11 есть enum class (не совсем стандартный, правда) и кое-что ещё. Я не проверял, как работает новый clang под XE10, но это только вопрос эффективности, «въедливости» и C++11 — миграцию на Юникод придётся проводить, как и раньше.

    Насчёт «въедливости». Я всегда считал, что G++ — самый «въедливый» компилятор. Но по статическому анализатору clang (встроен в Qt Creator, мой сейчас рабочий инструмент) кажется, что он переплюнул и этот рекорд. И сделать, чтобы один и тот же файл компилировался под древним Borland и суперсовременным clang — тяжеловато, по-моему. А именно это требовал Embarcadero от XE3 до XE8, если нужны версии и под x86, и под x64. Так что пусть BCC32 идёт туда, куда ему и дорога!

    Да, приходилось мигрировать на Юникод, когда появился Builder XE. Как я был рад!

    Знаю, что подхватит и сконвертирует XE2. Про более новые — не знаю ничего. Но даже если не сконвертирует — ничего не стоит построить новый проект с нуля и добавить туда все модули и формы. Но сконвертировать — это лишь половина вопроса; дальше придётся добиться компилируемости, а потом — и Юникода.
    Ответ написан
    Комментировать
  • Как решить проблему вывода из потока?

    @Mercury13
    Программист на «си с крестами» и не только
    #include <iostream>;
    Это не синтаксис Си, а директива препроцессора. Убери точку с запятой.

    #include <conio.h>;
    conio.h — это не стандартный хедер, а Windows-специфичный. Разумеется, вместо _getch() придётся использовать что-то другое.
    Ответ написан
    Комментировать