Ответы пользователя по тегу C++
  • Как узнать сколько байт прочитал std::ifstream.read()?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ну посмотрите в документацию же.

    Там английским по белому написано:
    The number of characters successfully read and stored by this function can be accessed by calling member gcount.


    И даже пример внизу есть.
    Ответ написан
    Комментировать
  • Почему решение задачи неправильное?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    is_subsequence написана с ошибкой. Что у вас там за алгоритм? Почему вы считатете, что оно должно работать?

    Оно, например, не работает на тесте s="abc" t="zzzzzcba". Ваша реализация скажет, что abc является подпоследовательностью, хотя на самом деле - нет.

    Еще хочется отдельно привлечь внимание к гениальности кода:
    if (is_sub)
            return true;
        else
            return false;


    Он кажется мне немного перемудренным.
    Ответ написан
    1 комментарий
  • Самомодифицирующийся код на c++ изменяющий значения переменой для нового запуска?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    На винде это можно сделать только в виде двух исполняемых файлов. Первый, внешний файл - просто запускает основной второй и ждет, когда он завершится. Когда вызываемый файл завершится, запустивший его может редактироват экзешник. Тут надо разбираться с форматом исполняемых файлов и дальше надо просто переписать байтики в определенной позиции в секции .rdata или что там будет.

    Но пользователь всегда может запускать второй файл напрямую. С этой проблемой еще можно как-то бороться если передавать какие-то секретные данные второй программе (основанные на известном состоянии этих меняющихся переменных). И основная программа при запуске должна их проверять. Или можно смотреть информацию о родительском процессе. А еще пользователь может прибить все ваши исполняемые файлы в диспетчере задач одновременно и следующий запуск будет с теми же самыми данными.

    В линуксе можно исполняемый файл редактировать, пока он запущен - поэтому там попроще. Чтобы бороться с sigkill стоит редактировать файл в самом начале после запуска.
    Ответ написан
  • Является ли хорошей практикой использование Stack Trace библотек в дебаг сборке?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Это нормальная практика. Например, ваш браузер скорее всего именно таким инструментом пользуется (если он на хромиуме основан).
    Ответ написан
    9 комментариев
  • Трёхмерный массив с разными размерами внутренних массивов?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Используйте vector<vector<vector<int>>>> - каждая строка/столбец могут быть любого нужного вам размера.

    Еще можно хранить ваши массивы как указатели в одном массиве указателей. Ведь эти сишные массивы - это по сути и есть указатели на начало. Вот только в таком виде вам придется как-то где-то помнить их размеры и вручную высчитывать индексацию в виде a[i*6+j], b[i*7+j].
    Ответ написан
    1 комментарий
  • Почему программа постоянно выводит 0? Как исправить?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы делите два int-а, там где формулу считаете. В языке C++ в этом случае происходит деление нацело. Поскольку числитель меньше знаменателя - всегда получается 0. Или static_cast-ом приводите к double, или тип где-то на double поменяйте (функции или переменной). Или, на худой конец, прибавляйте 0.0 к числителю или знаменателю.
    Ответ написан
    1 комментарий
  • Как переопределить операторы != и == в с++ для структуры?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Операторы должны возвращать bool и принимать константные ссылки на структуры.

    Но вообще-то раз вы итерируетесь по списку, вы сравниваете итраторы, а не структры. Поэтому достаточно просто использовать страндартную конструкцию:
    for (auto it = requests->begin(); it != requests->end(); ++it)


    И не надо ничего переопределять. Вы перепутали end и back. Первый возвращает итератор, а второй - элемент.
    Ответ написан
    2 комментария
  • Не получается найти пересечения multiset, в чем проблема?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Проблема в том, что итераторы unordered_set - имеют тип ForwardIterator. Варианты set_intersection, которые ждут вот такой вот итератор для результата, еще хотят и ExecutionPolicy.

    Но даже если вы поменяете тип у intersect, чтобы туда можно было вставлять ответ, ваш код не сработает, потому что set_intersection ждет упорядоченные интервалы. Вас unordered в названии контейнеров не смущает?
    Ответ написан
    Комментировать
  • Как считывать в массив целую строчку из файла?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Используйте getline.
    Ответ написан
    Комментировать
  • Идея с подбором всех вариантов не подойдет. Видимо нужна формула или аналог. Как решить?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Перебирайте a и b. Потом смотрите, какие значения может принимать c, чтобы ограничения выполнялись. Это будет отрезок чисел. Их не надо перебирать - можно их сразу все подсчитать. Например, если вы видите, что c<=10 удовлетворяет ограничения, то троек с текущими a, b - десять штук.
    Ответ написан
  • Как сменить разряды двухбайтового числа (С++)?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вам нужно сделать побитовое И с маской, где стоят 0 в нужных вам разрядах (и 1 в остальных). Маску можно задавать прямо бинарной или шестнадцатеричной константой.
    Ответ написан
    Комментировать
  • C++ Оператор и его перегрузка?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Ну вот так прнято в С++. Оператор префиксного инкремента (++i) имеет такую сигнатуру - он возвращает ссылку на измененный объект. Если выхотите чтобы у вашего класса Date можно было сделать ++date, то надо переопределить вот такой вот оператор. Это позволяет писать более читаемый и короткий код. Вместо date.IncremeantAndReturn() можно использовать идиоматичное ++date, или даже что-то вроде while (++date < deadline). Это не обязательно делать, но иногда это весьма удобно и полезно.

    Оператор должен возвращать измененное значение, поэтому и возвращается *this после его увеличения;

    В этом коде Сopy не используется. Оно тут не нужно вообще. копия понадобится для постфиксного инкримента (i++), который должен возвращать неизмененный объект.

    Передача *this в конструктор Copy - это для вызова конструктора копирования, чтобы, внезапно, создать копию текущего объекта. Подумайте, как вам скопировать текущий объект? Надо новому объекту присвоить текущий, или в конструктор передать ему текущий объект. Но как передать текущий объект? У вас есть указатель на него this. Разыменовав этот указатель (*this) вы как раз можете передать текущий объект куда надо.
    Ответ написан
    Комментировать
  • Как создать копию массива значений и массива указателей без std?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Чтобы скопировать массив можно воспользоваться memcpy, или делать это циклом.

    Массив указателей от массива значений не отличается ничем. Просто там значения - это указатели. Аккуратно не допустите ошибки при использовании sizeof - если ему передать сам массив (указатель), то это будет размер указателя, а не всего массива. Надо брать размер одного элемента и домножать на их количество.

    Если изначальный объект можно удалить, то вам надо переопределить оператор перемещения, а не копирования. Внутри ваши массивы - это просто указатели и их можно перемещать как переменные:
    keys_ = node.keys_;
    node.keys_ = nullptr;


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

    Так делать при копировании нельзя - ибо вы создаете несколько указателей на один и тот же массив и вообще непонятно, кто потом должен это удалять. Только при перемещении.

    Когда вы определили оператор перемещения (или конструктор перемещения), то далее оберните элемент источник в std::move() при присваивании или передаче в конструктор. Тогда вызовется действительно перемещающий метод.
    Ответ написан
    Комментировать
  • Не выводится отсортирований масив, лезет мусор из памяти, как исправить? run-time check failure #2 - stack around the variable 'c' was corrupted?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Выход за границу массива там где сортируете. Из этой левой памяти вы и получаете случайное значение.

    Смотрите внимательно, к каким индексам вы обращаетесь и какое значение может принимать переменная j.

    И еще, можно не сортировать итоговый массив, а формировать его уже отсортированным. Это работает сильно быстрее. Называется - процедура слияния.
    Ответ написан
    Комментировать
  • Почему у меня выводится непонятно что и как это испрвить?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Выводится ровно то, что вы попросили выводить - неинициализированный элемент массива c.
    Подумайте, чему равно a в конце программы?
    Ответ написан
    6 комментариев
  • Почему меняется значение переменной после передачи значения в функцию (C++)?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    У вас в input_matrix выход за границы массива: в массиве n-1 элемент, а вы читаете n.

    Массив лежит на стеке, там же где локальная переменная n. Так получилось, что n лежит сразу за matrix (или в пределах восьми байт) и оказывается испорчена. Данные кажутся вам случайными, потому что читаете вы double и какая-то его часть попадает в область памяти int n.
    Ответ написан
  • Почему дружественная функция, определённая внутри класса с первым параметром встроенного типа, недоступна вне определения класса?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вы пытаетесь вызвать f1 и т.д., как будто это члены класса A. Но подумайте, какой смысл объявлять члены класса friend? Зачем вообще дружественность нужна? Чтобы иметь доступ к приватным членам класса, но ведь члены класса и так имеют туда доступ. Это бесмыссленная операция.

    Но так уж стандарт сделан, что вместо ошибки компиляции, определенные через friend функции становятся глобальными.

    По идее вы в классе должны их только объявлять (сигнатура без тела), а определение (тело функции) должно быть уже снаружи где-то, как вы с f1 сделали.

    Почему f5 не находится? Попробуйте передать туда, допустим a. Компилятор, внезапно, найдет функцию и ругнется, что не может преобразовать A к int. Но если передать туда int, то компилятор функцию потеряет.

    Тут хитрая магия описанная в стандарте - всякие нагромождения правил посика имен.
    В стандарте сказано, что вот при определении friend функций:
    A name first declared in a friend declaration within a class or class template X becomes a member of the innermost enclosing namespace of X, but is not visible for lookup (except argument-dependent lookup that considers X) unless a matching declaration at the namespace scope is provided - see namespaces for details.


    Я не знаю, как это внятно объяснить, вот просто не работает и все. Стандарт такой. С остальными функциями срабатывает, потому что там в аргументах есть A, поэтому объявления в классе каким-то образом попадают в область поиска имен.

    Просто не надо определять функции-друзей в классе. Это не имеет смысла. Или делайте там статичные функции, или определяйте всю функцию во внешнем пространстве имен а в классе указывайте, что она имеет доступ ко всему классу.
    Ответ написан
    1 комментарий
  • Решение задачи совсем не пойму ее?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Неужели так сложно проверить, что каждый
    следующий элемент не
    меньше предыдущего


    А с массивом-то сделать можете?
    Ответ написан
    Комментировать
  • Яндекс.Практикум C++ Что я делаю не так?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Вся проверка должна быть query[i] == ' '

    to_string(32) - вернет вам "32" вместо пробела. Тогда уж можно делать (char)32 или static_cast<char>(32). Но ' ' - все равно лучше.

    И еще вы не выводите длину всей строки в конце - ведь там всегда заканчивается слово (может быть пустое).
    Ответ написан
  • Как посчитать количество циклов у перестановки?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Как-то хитро встроить подсчет циклов в генерацию перестановок никак не получится.

    Поэтому, алгоритм простой - посчитать циклы по одному.
    Фактически, перестановка - это граф и вам надо подсчитать в нем количество компонент связности. Надо использовать DFS. Но граф очень простой, поэтому DFS выраждается в тупо цикл.

    Заведите массив флагов длинной с перестановку. Пройдитесь по всем позициям и, если текущая не помечена, запускайте от нее второй цикл, который пометит ее и перейдет в позицию по перестановке (row[i]) и пометит там и опять перейдет и так далее, пока не наткнется на уже помеченную позицию. Так вы побойдете один цикл и пометите все позиции в нем. Поэтому прибавьте 1 к счетчику, когда будете запускать внутренний цикл.

    В решении будет 2 вложенных цикла, внешний - удобнее всего делать for, внутренний можно тоже делать for или while, но в for будет вместо инкримента переход по перестановке. И эти 2 вложенных цикла суммарно обойдут все позиции по одному разу, поэтому время работы алгоритма - линейное.
    Ответ написан
    Комментировать