Ответы пользователя по тегу C++
  • Почему в массив размером N можно положить больше чем N элементов?

    @res2001
    Developer, ex-admin
    В malloc при передаче в качестве аргумента нуля возвращаемое значение не определено (implementation-defined). Так что фиг знает что там вам вернул маллок. Но раз программа не падает, то, возможно, он вернул какой-то указатель на стек, а в стеке у вас есть ~8МБ - развлекайтесь.
    В общем не нужно так делать. На другом компиляторе (или на том же, но другой версии) поведение может быть совсем другим.
    Ответ написан
    Комментировать
  • Как в данном случае записывать результат недоигранной игры в бинарный файл?

    @res2001
    Developer, ex-admin
    Сохраняйте имена игроков и массив cells. Т.к. вся информация символьная, то ваш бинарный файл будет вполне себе текстовый. Есть смысл и делать его именно текстовым, где в каждой строке будет находится один элемент данных.
    Ответ написан
    Комментировать
  • Как кидать исключения при работе с try catch?

    @res2001
    Developer, ex-admin
    Сишные функции не вызывают исключений. В Си их просто нет. Поэтому помещать их в try/catch нет смысла - проверяйте возвращаемые значения по старинке. Если хотите, можете написать обертки для стандартных функций, генерирующие исключения в случае ошибки. А еще лучше использовать std::fstream - вы же пишите на С++, так и пользуйтесь плюсовой стандартной библиотекой, а не Сишной.
    void foo() {
        int *smth;
        try {
            smth = new int[100];
            if (5 < 4) {
                std::runtime_error("Беда");
            }
        } catch (std::runtime_error &e) {
            e.what();
        }
        delete[] smth;
    }

    new генерирует std::bad_alloc, если произойдет исключение - память не выделилась и ничего удалять не надо.
    Ответ написан
    2 комментария
  • Длина файла в c++?

    @res2001
    Developer, ex-admin
    Не нужно вам так: for(i =0; i<=длина файла -1;i++)
    Читайте пока не будет eof() или ошибки, обычно делают примерно так:
    while(f.good()) { f.read() }

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

    @res2001
    Developer, ex-admin
    1. std::stoi/std::strtoi и подобные функции
    Примеры тут: https://en.cppreference.com/w/cpp/string/basic_str...
    2. Что именно вам не понятно в применении констант? Приведите пример непонятного?
    const int bad_id =  -1;
    ...
    int new_id = bad_id;

    Смысл в том, чтобы применять не саму константу (в примере -1), а ее именованный эквивалент, имя которого должно иметь смысл для читающего код. При этом по коду у вас может быть несколько одинаковых констант с разным смыслом. Для каждой такой константы нужно создать свою символьную константу.
    https://ravesli.com/urok-37-simvolnye-konstanty-co...
    Ответ написан
    Комментировать
  • Как сделать чтобы введенное число не было больше 1000?

    @res2001
    Developer, ex-admin
    Если по простому, то вам нужно проверять введенное значение и если оно выходит из нужного диапазона повторять попытку ввода.
    Если же хочется, чтоб пользователь в принципе не мог ввести число вне диапазона, то нужно выкинуть весь стандартный ввод/вывод, читать ввод посимвольно на каждый введенный символ проверять диапазон, если очередной прочитаный символ цифра и получившееся число вместе с новой цифрой укладывается в диапазон, то самому ее допечатывать на экране, если не укладывается - игнорировать (отбрасывать и не печатать). Как-то так. Забейте, овчинка не стоит выделки, используйте первый вариант. Хотя это было бы полезным опытом, если вы хотите научиться программировать.
    Ответ написан
    1 комментарий
  • Как решить проблему с устаревшей функцией?

    @res2001
    Developer, ex-admin
    Установите libpng из пакетов в систему, поставьте к ней dev пакет и используйте ее в своем проекте.
    В пакетах содержится версия libpng совместимая с вашей системой.
    glibc тесно связана с ядром, поэтому просто так ее не собрать и версию не изменить. Она идет в комплекте с ядром.
    Ответ написан
  • Можно ли отлавливать инжект dll в приложение?

    @res2001
    Developer, ex-admin
    Изучите методы инжектирования и повесьте свои хуки на соответствующие системные вызовы.
    Посмотрите сюда для примера: https://habr.com/ru/company/icl_services/blog/324718/
    https://docs.microsoft.com/ru-ru/windows/win32/api...
    https://docs.microsoft.com/en-us/windows/win32/api...
    Ответ написан
  • Почему при делении 0 на -5 получается -0?

    @res2001
    Developer, ex-admin
    Можно делать примерно так:
    #include <cfloat>
    ...
    if (res > -DBL_EPSILON && res < DBL_EPSILON) res = 0;
    cout << res;

    В качестве DBL_EPSILON вы можете выбрать другое число, которое вам более удобно.
    Красиво тут не получится. Так же как бесполезно делать точное сравнение (==) двух чисел с плавающей точкой.
    Ответ написан
    2 комментария
  • Как создать компоратор для вектора структур?

    @res2001
    Developer, ex-admin
    Помогите написать компоратор для этого дела или объясните, что можно написать по-другому.

    Какие проблемы то?
    Вот как описал сам процесс сравнения так и реализуешь компаратор.
    Т.е. сначала проверяешь баллы. Если баллы не равны, сразу возвращаешь соответствующее значение.
    Если баллы равны начинаешь проверять name.
    Ответ написан
  • Как проверить на int?

    @res2001
    Developer, ex-admin
    У вас же есть некий диапазон корректных значений, которые вы ждете от пользователя?
    Перед вводом присвойте переменной некорректное значение.
    После ввода проверяйте значение на корректность.
    Вот и вся проверка.

    Вообще любой пользовательский ввод надо проверять на корректность, а так же содержимое конфигов и т.п.
    Ответ написан
    2 комментария
  • Как выводить русские буквы в консоль на С++?

    @res2001
    Developer, ex-admin
    Вечная проблема :-)
    Каждый начинающий виндовый С++ программист должен пройти через это!

    1. Виндовая командная строка по умолчанию имеет кодировку cp866 (да-да, не cp1251). Не рекомендую выводить в UTF8, т.к. cmd до сих пор коряво работает с этой кодировкой.
    2. cmd и консоль powershell - это разные консоли
    3. Компилятор и стандартная библиотека (cin/cout) никак не конвертируют кодировки при вводе/выводе.
    (Возможно преобразование можно как-то задать, но по умолчанию это не делается.)
    4. Компилятор никак не преобразует ваши текстовые строки в программе при сборке, т.е. в какой кодировке вы написали строковую константу, та же кодировка будет выведена на консоль. Таким образом - имеет значение в какой кодировке у вас исходники!
    5. Кодировку в консоли можно поменять из самой консоли командой chcp. Часто так и делают. В русской винде 2 широко используемые кодировки консоли: cp866 и cp1251. Не стоит надеяться на то, что программа всегда будет запускаться только при одной кодировке.

    Исходя из вышенаписанного:
    1. Исходники всегда пишем в UTF8
    2. Перед выводом всегда преобразуем UTF8 в кодировку консоли. После ввода - то же самое. Есть соответствующие функции в WinAPI.
    3. Никогда не меняем принудительно кодировку консоли - это не удобно пользователям программы

    Для самого простого варианта - вы можете написать исходники в cp866 и по умолчанию в cmd у вас все будет нормально с кодировками.

    Удачи!
    Ответ написан
    Комментировать
  • Создание случайной строки в момент компиляции?

    @res2001
    Developer, ex-admin
    1.Текущий timestamp часто берут для инициализации стандартного С/С++ генератора случайных чисел.
    Пример можно найти, например тут: https://en.cppreference.com/w/cpp/numeric/random/srand

    2.Вам придется реализовать свой собственный constexpr rand(), т.к. стандартный не constexpr.

    3.Вам не нужно в принципе вызывать MessageBox и любые подобные функции на стадии компиляции программы.
    constexpr функции выполняются компилятором, поэтому на них накладываются достаточно серьезные ограничения. Когда программа исполняется вместо вызова constexpr функции уже стоит ранее вычисленное компилятором значение.
    Ответ написан
    8 комментариев
  • Как включить программу в автозагрузке C++?

    @res2001
    Developer, ex-admin
    Последний параметр в RegSetValueEx для REG_SZ должен содержать длину строки + 1 на завершающий нулевой символ (strlen(arr)+1) (https://docs.microsoft.com/en-us/windows/win32/api...)

    Не используйте MAX_PATH - это древний уже неактуальный вариант. Читайте до просветления: https://docs.microsoft.com/en-us/windows/win32/fil...
    Ответ написан
    Комментировать
  • Как отпарить POST запрос на сервер на чистом Visual С++ или WinApi по HTTPS и HTTP протоколам?

    @res2001
    Developer, ex-admin
    Можно использовать функционал микрософтовской библиотеке wininet. Есть по умолчанию в винде. Можете начать отсюда:
    https://docs.microsoft.com/en-us/windows/win32/api...
    https://docs.microsoft.com/en-us/windows/win32/api...

    Правда я не знаю, что там у нее с поддержкой HTTPS.
    Ответ написан
    Комментировать
  • Определение для переменной укзателя double?

    @res2001
    Developer, ex-admin
    double *dPtr;
    :)
    Ответ написан
    Комментировать
  • Библиотека и пространство имен. В чем разница?

    @res2001
    Developer, ex-admin
    Когда вы пишите код, то вы работаете с пространством имен.
    После того как вы собрали свою программу и запустили ее, программа работает с библиотекой, там уже нет никаких пространств имен.
    В библиотеке может быть несколько пространств имен или не одного (точнее вся библиотека размещается в одном глобальном пространстве имен).

    Если опуститься ниже, то библиотека это файл *.dll и/или *.lib (для винды), пространство имен объявляется в *.h файлах.
    Ответ написан
    Комментировать
  • Моно ли присвоить переменной/указателю определённый адрес в памяти?

    @res2001
    Developer, ex-admin
    Присвоить адрес указателю можно. По сути указатель - это просто целочисленная переменная, разрядность которой равна разрядности адресной шины. Но арифметические операции с указателями имеют правила отличные от обычной арифметики (адресная арифметика).

    Обращаться по присвоенному адресу (делать разыменование, получать значение лежащее по указанному адресу), если вы точно не знаете, что делаете, не стоит, т.к. это может привести к access violation (segmentation fault).
    В современных ОС используется виртуальная память, из-за чего память используемая программой должна быть корректно выделена с помощью механизмов предоставляемых ОС (new).
    В микроконтроллерах нет виртуальной памяти, поэтому вся память программе доступна сразу. Там вы можете свободно обращаться к любому адресу в пределах физически доступного адресного пространства.
    Ответ написан
    Комментировать
  • Как поменять кодировку при записи данных в файл?

    @res2001
    Developer, ex-admin
    Нужно перекодировать текст в кодировку, которую вы хотите видеть в файле.
    Или сразу писать исходники в этой кодировке.

    А вообще найдите редактор, который понимает разные кодировки и используйте его для просмотра текста. На этапе изучения языка, возможно, нет смысла вникать в нюансы кодировок. Могу посоветовать Notepad++ или встроенный редактор Far manager.

    В винде с этим все достаточно запутано.
    Но кодировки в файле - это еще простой случай.
    Когда попытаетесь писать кирилические символы в консоль, вот тогда сможете полностью прочувствоввать всю глубину вопроса, если, конечно, на это хватит терпенья.
    Ответ написан
    2 комментария
  • Зачем разделять проект на кучу файлов и как научиться разбираться в них?

    @res2001
    Developer, ex-admin
    Когда проект большой просто удобно разложить отдельные мало связанные друг с другом части в разные файлы.
    Большие проекты могут насчитывать миллионы строк кода, это будет много даже в мегабайтах. Не каждый текстовый редактор сможет просто открыть такой документ, а сохранение будет каждый раз приводить к ощутимой задержке.
    Кроме того часто не только в файлы раскладывают, а еще и отдельные папки заводят, если части вообще не зависимые.

    Вы не пишите сразу весь проект и 99% существующего кода вам не нужна вот прям сейчас. В текущий момент времени вы работаете над каким-то конкретным участком кода и функционалом. Удобно когда весь код находится под рукой. Да, когда код разбит на файлы, часто работая над одним функционалом, приходится держать открытыми несколько файлов, но их количество ограничено и их размер достаточно не большой.
    Если вы только начали изучать крупный проект, то в начале будет тяжело ориентироваться, но уже через несколько дней изучения кода это не будет для вас большой проблемой. Хорошая IDE то же помогает в этом случае.

    Части проекта помещенные в отдельные файлы вы можете использовать на прямую в другом проекте как есть, без копипасты и поддержания одного и того же кода в разных проектах, просто скопировав файлы в другой проект или подключив submodule в гите.
    Ответ написан
    Комментировать