Ответы пользователя по тегу C++
  • В чём отличие между char* и char[]?

    @lorc
    В случае выделения на стеке или в глобальных переменных - разница очень большая. char* - это просто указатель. Как тут правильно сказали - у вас будет два указателя на один и тот же строковый литерал.

    char[] - создание массива на стеке. Соответственно, у вас там будут хранится не два указателя, а два массива. Вы сравниваете их и они очевидно не равны.

    Вот пример: https://ideone.com/pIhUvq. Как видите, в одном случае у нас 64-битный указатель, а в другом - массив.

    А вот в параметрах функции - действительно, большой разницы нет.
    Ответ написан
    Комментировать
  • Почему при дебаге появляется can't increment vector iterator past end?

    @lorc
    Потому что нельзя изменять вектор, по которому вы итерируете. Вот что пишут про std::vector::erase:

    Invalidates iterators and references at or after the point of the erase, including the end() iterator.
    Ответ написан
    5 комментариев
  • Почему не работает (Chain of Responsibilty)?

    @lorc
    Подозреваю, что должно быть вот так:

    void SetNextHandler(Handler* next_handler) {  
            if (next) {
                next->SetNextHandler(next_handler); // <- next, не this
            } else {
                this->next = next_handler;
            }
        }


    Иначе у вас бесконечная рекурсия получится.

    Но вообще, это не самый оптимальный алгоритм, ибо сложность добавления нового хендлера - O(N), хотя можно было бы сделать O(1), если не важен порядок вызова.

    А еще, можно бы завести виртуальную функцию, которая будет занимать только хендлингом. Это сделает код более надежным и позволит избежать Handler::HandleRequest(data); в конце каждого хендлера.
    Ответ написан
    3 комментария
  • Не работает sort, но явную ошибку в коде не находит. Как исправить?

    @lorc
    Вы бы хотя бы привели сообщение об ошибке.

    Проблема в том, что ваш компаратор - это метод класса. Было бы странно использовать его без объекта. На что вам компилятор и намекает.

    Вот исправленный вариант:

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <list>
    #include <string>
    #include <fstream>
    #include <cmath>
    #include <functional>
    
    using namespace std;
    
    class Finder
    {
    public:
        list<vector<double>> lines; //список, в котором информация
        vector<double> input = {0, 0}; //массив, который вводит пользователь
        string path; //путь к файлу
    
        Finder(string path, string numbs) //конструктор открывает файл и создает входной массив
        {
            this->path = path;
    
            int l = numbs.size();
            vector<double> input;
    
            for (int i = 0; i < l; i++)
            {
                string buffer = "";
    
                if (numbs[i] != ' ')
                {
                    buffer += numbs[i];
                }
                else
                {
                    input.push_back(stod(buffer));
                    buffer = "";
                }
            }
    
            this->input = input;
            cout << "Initialization was successful" << endl;
        }
    
        void GetData() //да, загружать из файла в память обязательно
        {
            ifstream fin(path);
            string line;
    
            while (getline(fin, line))
            {
                int l = line.size();
                string buffer = "";
                vector<double> numbers;
    
                for (int i = 0; i < l; i++)
                {
                    if (line[i] != ' ')
                    {
                        buffer += line[i];
                    }
                    else
                    {
                        numbers.push_back(stod(buffer));
                        buffer = "";
                    }
                }
    
                this->lines.push_back(numbers);
            }
    
            fin.close();
            cout << lines.size();
        }
    
        double GetDistance(vector<double> a) //расчет расстояним между точками
        {
            int l = this->input.size();
            double sum = 0;
    
            for (int i = 0; i < l; i++)
            {
                double el_i = this->input.at(i);
                double el_a = a.at(i);
    
                sum += pow((el_i - el_a), 2);
            }
    
            return sqrt(sum);
        }
    
        bool compareTo(vector<double> a, vector<double> b) //компаратор
        {
            return GetDistance(a) < GetDistance(b);
        }
    
        void ShowHeigbor() //для пользователя
        {
        	using namespace std::placeholders;  // for _1, _2, _3...
    
            this->lines.sort(std::bind(&Finder::compareTo, this, _1, _2));
        }
    };
    
    int main()
    {
        string inp;
        cout << "Input vector: ";
        cin >> inp;
    
        Finder f{"data.txt", inp};
    
        f.GetData();
        //f.ShowHeigbor();
    }
    Ответ написан
    4 комментария
  • В чём разница способов подключения кириллицы?

    @lorc
    Исходя из опытов выше, возникает вопрос: а чем различаются эти два варианта подключения кириллицы к проекту?


    Практически всем. На самом деле, у вас есть две сущности - ваша программа и терминал. Ваша программа читает данные из stdin и пишет в stdout/stderr. Терминал же занимается тем, что отображает данные на экран. Для вас критически важно, чтобы программа передавала данные в той кодировке, в которой их ожидает увидеть терминал.

    Соотвественно, когда вы вызываете SetConsoleOutputCP(1251), вы говорите терминалу "ожидай данные в кодировке СР1251". Это плохо по нескольким причинам:

    • Это чисто виндова функция. Она не переносима на другие платформы
    • СР1251 - однобайтовая кодировка и ее лучше не использовать в 21 веке. Нужен юникод.
    • Другие программы, работающие в этом же терминале (например echo) не знают что вы поменяли кодировку терминала. Потому вы и видите мусор.


    Когда вы вызываете setlocale - вы говорите своей программе "возьми настройки кодировки из окружения и выдавай текст в ней". В результате вы подстраиваетесь под терминал и используете ту кодировку, в которой он работает. Скорее всего это будет юникод. В этом варианте все минусы превращаются в плюсы - это переносимо, это юникод, остальные программы будут работать нормально.

    Кстати, вызывать setlocale с параметром Russian не совсем верно. Нужно использовать пустую строку -"". Интересно, что я уже второй раз вижу на тостере именно "Russian". Кажется, где-то по рунету гуляет неправильный пример.
    Ответ написан
    Комментировать
  • Не получается объявить двухмерный динамический массив?

    @lorc
    int newMapLineAndColumnSize = sqrt(arrayLineAndColumnSize * coefficient);

    Тут точно sqrt() нужен? Мне кажется, что без него будет лучше.
    Ответ написан
  • Как получить вывод консоли?

    @lorc
    к сожалению с system() у вас так не получится. Вам нужно пойти длинным и сложным путем - через fork, pipe, dup и execve.

    В принципе вот тут расписано более-менее.

    Возможно есть библиотека, которая все это инкапсулирует и предоставляет удобный интерфейс. Но я такой не встречал.
    Ответ написан
    Комментировать
  • "ошибка сегментирования" как исправить(С++)?

    @lorc
    В данном случае ошибка в строке virus.getline(str,255);. Там должно быть virus.getline(vir,255);. Именно это приводит к segfault. Но как я написал в комментарии к другому ответу - это не единственная проблема в вашем коде.
    Ответ написан
    3 комментария
  • T - это массив из 3 указателей на структуры с типом car?

    @lorc
    Это указатель на массив из трех структур типа `car`
    Ответ написан