Задать вопрос
  • Внешний ip перенаправляет на роутер, как убрать?

    @res2001
    Developer, ex-admin
    Сделайте так, чтоб компьютеры внутри сети ходили на внутренние сервисы по внутреннему адресу, а не по внешнему. Это можно сделать добавив соответствующие записи в файл hosts.
    Ответ написан
  • Как корректно вывести функцию в байтовом виде?

    @res2001
    Developer, ex-admin
    Что мешает предусмотреть варианты когда f < _end и f > _end?
    https://godbolt.org/z/8M33E4PYo
    Но это не гарантирует, что компилятор чего-нибудь не вставит между функциями. О чем и говорит итоговый выхлоп.
    И еще выхлоп может быть разным при разных флагах оптимизации: -O0/1/2
    Ответ написан
    Комментировать
  • Что стоит делать в 16 лет, если планирую стать специалистом в системном программировании?

    @res2001
    Developer, ex-admin
    В 16 лет, если вы еще в школе, следует готовиться к поступлению в профильный институт/университет.

    Раз вы уже выбрали себе примерное направление будущей деятельности, то есть смысл просмотреть программу факультета и выбрать наиболее для вас подходящую специальность.
    Это не обязательно должно быть именно "системное программирование", т.к. сюда можно отнести много чего, но это должно быть что-то приближенное либо к железу (встраиваемые системы) либо к ядру ОС и в программе обязательно должен быть курс С/С++ - без них на сегодня делать в системном программировании нечего, ассемблера в программе может и не быть - это не столь важно на самом деле.
    Ответ написан
    Комментировать
  • Как считать из stdin русский текст и вывести его как wchar_t?

    @res2001
    Developer, ex-admin
    blecked88, Было свободное время, провел несколько экспериментов, т.к. про _setmode впервые у тебя увидел.

    Если вместо _O_U16TEXT использовать _O_U8TEXT, то ввод/вывод будет преобразовываться в UTF8, что более привычно (чем UTF16). Особенно это заметно при выводе строк (ввод как раз лучше оставить в UTF16) в файл (например если в консоли сделать перенаправление вывода в файл, а затем файл открыть в текстовом редакторе).

    Вообще, учитывая, что кодировку консоли может устанавливать пользователь самостоятельно, то чтоб было совсем красиво надо перекодировать выводимые строки в кодировку консоли, а не принудительно устанавливать свою кодировку через setmode/SetConsoleCP и т.п..
    Накидал пример, как это может выглядеть:
    Пример
    #define _CRT_SECURE_NO_WARNINGS
    #include <stddef.h>
    #include <stdint.h>
    #include <locale.h>
    #include <wchar.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <assert.h>
    #include <io.h>
    #include <fcntl.h>
    #include <Windows.h>
    
    UINT cpo = 0;
    
    void print_wide(const wchar_t* wstr)
    {
      assert(cpo != 0);
      static char buf[512];
      if(WideCharToMultiByte(cpo, 0, wstr, -1, buf, 512, NULL, NULL) != 0)
        printf("multibyte string: \"%s\"\n", buf);
      else
        printf("Error WideCharToMultiByte()\n");
    }
    
    void main()
    {
      cpo = GetConsoleOutputCP();
      _setmode(_fileno(stdin), _O_U16TEXT);
      wchar_t wbuf[512];
      if (wscanf(L"%511ls", wbuf) == 1)
          print_wide(wbuf);
      else
          printf("Error wscanf()\n");
    
    //  const wchar_t *str = L"Привет мир!\u00df\u6c34\U0001f34c";
    //  print_wide(str);
    }

    Схема такая: внутри программы все строки хранятся как wchar_t, литералы с префиксом L. Для консольного ввода принудительно выставляем преобразование в wchar_t с помощью _setmode(U16TEXT) и используем фунции w/wcs. Настройки консольного вывода не меняем, а используем установленные пользователем или системой.
    Для вывода строк:
    1. в начале main узнаем текущую кодовую страницу консоли
    2. в функции print_wide применяем преобразование кодировки с помощью стандартной функции WinAPI.
    Пример взят отсюда. И адаптирован для ввода. Функция преобразования заменена, т.к. функция wcsrtombs из стандартной библиотеки преобразовывает только в UTF8, но не в другие доступные в консоли винды кодировки.
    Таким образом благодаря _setmode и функциям w/wcs ввод автоматически преобразовывается в wchar_t, а вывод "руками" преобразовывается в текущую кодировку консоли.
    В онлайн компиляторах пример гонять бесполезно - не понятно какие кодировки у них там при запуске.
    При компиляции в msvc файл с исходником сохранять в UTF8, добавить ключ компилятора /utf-8 (или можно сохранить файл с BOM).
    Для тестов меняем кодировки консоли руками (chcp 866/1251/65001), перенаправляем вывод в файл и смотрим кодировку текста в файле каким-нибудь доступным редактором (notepad++/far edit/...) - она должна совпадать с кодировкой установленной командой chcp.

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

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

    Статьи на тему:
    https://habr.com/ru/companies/xakep/articles/257895/
    https://habr.com/ru/companies/ruvds/articles/645325/
    https://habr.com/ru/articles/731614/
    Полезные ссылки:
    https://learn.microsoft.com/ru-ru/windows/console/...
    https://learn.microsoft.com/ru-ru/windows/win32/in...
    https://learn.microsoft.com/ru-ru/windows/win32/ap...
    https://learn.microsoft.com/ru-ru/cpp/c-runtime-li...
    https://learn.microsoft.com/ru-ru/cpp/c-runtime-li...
    Ответ написан
    Комментировать
  • Возможно ли реализовать TCP на Delphi?

    @res2001
    Developer, ex-admin
    Написал ответ в комментариях тут.
    Ответ написан
    Комментировать
  • Как сделать линковку в проекте на с++ Visual Studio?

    @res2001
    Developer, ex-admin
    Ответ в комментарии
    Ответ написан
    Комментировать
  • Существуют ли эталонно красиво написанные программы?

    @res2001
    Developer, ex-admin
    Код должен решать определенную задачу. Читать абстрактный код без понимания сути решаемой им задачи - бессмысленное занятие. Т.е. вы должны сначала вникнуть в задачу и хотя бы в черне представить как бы вы ее решали. В этом случае, читая код, уже можно оценивать те приемы, которые там применены.
    У меня сложилась такая практика: когда мне требуется использовать библиотеку, в которой реализован нужный мне функционал (т.е. я изначально уже знаю какую задачу должна решать библиотека), я сначала читаю обзорно документацию на нее, потом лезу в исходники и смотрю как оно там все устроено. Некоторые библиотеки после такого анализа отбраковываются, из других можно вынести для себя что-то полезное, но в любом случае начинаешь лучше понимать как работает библиотека.
    На изучение кода толстых библиотек может уйти много времени, поэтому смотрю только какую-то небольшую часть, которая нужна в данном конкретном случае.
    Многие просмотренные мной библиотеки написаны не плохо с моей точки зрения, но на сколько они "эталонно красивы" судить не берусь.
    В целом считаю, что читать чужой код - полезный навык. Но все таки умение программировать самому еще более полезный. Поэтому надо правильно расставить приоритеты.
    Ответ написан
    Комментировать
  • Почему в локальном репозитории Git основная ветка - называется master, а в GitHub, основная ветка - main?

    @res2001
    Developer, ex-admin
    Попробуйте так:
    git push origin/main master
    Почему у вас ветки разбежались - могут быть разные причины, но все дело рук человеческих. Можете сделать ветку с таким названием как вам удобно, а старую удалить.
    Сами имена веток master/main - никак не стандартизированы, просто общепринятые названия. Вы вольны использовать любое название вашей основной ветки.
    https://stackoverflow.com/questions/69786766/git-g...
    Ответ написан
    Комментировать
  • Что такое уровни абстракции в книге 'Чистый код' Мартина?

    @res2001
    Developer, ex-admin
    А мне это вообще не очевидно, ведь тут подразумевается, что в методе несколько уровней абстракции

    Тут не несколько уровней абстракции. Тут не хватает абстракций, а потому и возникает проблема.
    совершенно очевидно выполняет более одной операции

    Для данного примера очевидно, что "более одной операции" - это расчет выплат для разных типов сотрудников.
    А раз разные типы, то значит в этом методе, по мнению автора, не хватает абстракций для типов сотрудников.
    Об этом же говорит и способ решения проблемы, предлагаемый автором в следующем листинге - он предлагает применить полиморфизм, т.е. создать иерархию классов по типам сотрудников, которые будут наследоваться от абстрактного класса Employee и сделать "абстрактную фабрику", которая будет создавать объект нужного класса сотрудника в зависимости от переданного типа сотрудника. Тогда каждый дочерний класс сотрудника будет переопределять свой метод calculatePay только для своего типа. Вышестоящий код благодаря полиморфизму получит правильный расчет выплат для данного сотрудника без switch.
    Точнее в решении switch остается, но на уровне абстрактной фабрики, когда делается выбор какой объект сотрудника надо создавать. И это единственное место, где будет такой switch. Если же не использовать полиморфизм, то потенциально может существовать множество мест, где понадобится использовать switch по типам сотрудников.
    Ответ написан
    Комментировать
  • Сетевые папки, обнаружение компьютера в сети Win10?

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

    Могу только добавить, что одноранговая (без контроллера домена) сеть микрософт даже когда она настроена правильно, может время от времени сбоить. Это обычно выглядит так, что компы не могут получить доступ друг к другу по имени, хотя вчера все работало. Связано это с выбором роли master browser в сети - эти выборы не всегда могут закончится успешно и в сети может появиться 2 master browser. При этом доступ по IP адресу на те же компы будет проходить нормально.
    В целом, если с этим не столкнетесь, то можно и не париться. Но если эта проблема будет возникать, то ее можно решить тонкой настройкой компов - задания роли master browser вручную. Об этом в интернете есть достаточно информации.
    Лично я, когда приходилось использовать одноранговую сеть в винде, предпочитал доступ по IP адресам, чтоб не заморачиваться с тонкой настройкой.
    Ответ написан
    Комментировать
  • Можно ли частично изменить маску подсети в сети организации?

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

    @res2001
    Developer, ex-admin
    Обычно достаточно добавить сеть в Частный профиль и по умолчанию все остальное срабатывает.

    Вообще общий доступ настраивается в win11: Settings->Network&Internet->Advanced Network Settings->Advanced Sharing Settings: для Private Networks включить все что там есть.
    Для All Networks включить Password protection sharing и выбрать режим шифрования (128 бит рекомендуется).
    У меня все это вроде бы было включено по умолчанию, но не поручусь.
    Если у вас в сети нет домена и АД, то желательно на всех компах настроить одну и ту же рабочую группу для одноранговых сетей микрософт: Setting->System->About->Domain and Workgroup->Change (после изменения возможно потребуется перезагрузка). Там же можно задать и имя компьютера в сети.
    Ну и на последок в свойствах сетевого адаптера, который используется для доступа в локальную сеть (Settings->Network&Internet->Advanced Network Settings->сверху в списке раскрываем нужный сетевой адаптер->More Adapter Options->Edit) должны быть включены Client for Microsoft Networks, File and Printer Sharing for Microsoft Networks. Эти настройки по умолчанию включены.
    В винде начиная с вин10 довольно часто меняют названия и местоположения некоторых настроек. Все вышеприведенное актуально для Win11 23H2.

    Правила для фаервола по умолчанию разрешают доступ служб microsoft network для приватного профиля, так что тут ничего настраивать обычно не нужно.

    После этого другие компы должны начать видеть компьютер в сети и иметь возможно использовать его расшаренные ресурсы регистрируясь по логину/паролю. Для этих целей можно завести отдельных пользователей и группы, которым раздавать права на расшаренные ресурсы.
    Ответ написан
    Комментировать
  • Как настроить CMake на установку пакетов?

    @res2001
    Developer, ex-admin
    Самому заниматься установкой зависимостей есть смысл только для статически линкуемых библиотек. В этом случае самый простой вариант такие библиотеки оформить например как субмодуль git. Тогда при клонировании вашего репозитория скачаются исходники библиотеки. В cmake просто собираете ее как отдельный таргет и используете по назначению. Хорошо если библиотека уже поддерживает сборку через cmake - будет меньше возни. Если нет, то придется написать самому для нее CMakeLists.txt.

    Для динамических библиотек стоит оставить удовлетворение зависимостей пользователю, потому что вариантов пакетных менеджеров много (вы хотите их все поддерживать?). В вашем CMakeLists.txt нужно только сделать тем или иным способом поиск установленного пакета и если его нет - выдачу ошибки и завершение сборки. Такие механизмы в cmake есть. Можно использовать выше приведенный find_package или например pkg_check_modules (который в свою очередь использует утилиту pkg-config).
    Почти все более-менее серьезные приложения не пытаются установить самостоятельно свои зависимости при сборке. Можете проверить. Например: https://github.com/nginx/nginx?tab=readme-ov-file#...

    Вы можете дополнительно к сборке приложения добавить и создание пакета для пакетного менеджера (или для нескольких пакетных менеджеров). Вот тут то вы и укажите необходимые приложению зависимости (в разных дистрибутивах линукс пакеты с зависимостями могут называться по разному). И тогда, когда пользователь будет устанавливать ваш пакет через пакетный менеджер все зависимости установятся автоматически.
    В cmake есть механизм для создания пакетов для разных пакетных менеджеров: https://cmake.org/cmake/help/book/mastering-cmake/...
    Ответ написан
    2 комментария
  • Кириллица в c++. Что с ней не так?

    @res2001
    Developer, ex-admin
    В виндовой консоли есть 2 русские кодировки cp866 и cp1251. Причем cp866 используется по умолчанию! Так же есть еще 65001 (UTF8), которая то же умеет в кирилицу. Пользователь консоли может менять кодировку по собственному усмотрению (команда chcp /?). Как правило встроенные виндовые утилиты командной строки правильно работают с любой установленной кодировкой (можете сами в этом убедиться).

    Дополнительно к кодировкам самой консоли винды добавляется еще кодировка в которой написаны ваши исходники. Кодировка исходников должна быть совместима с кодировкой консоли. Если не совместима, то нужно или переключать кодировку консоли (что для консольных утилит не хорошо - это вам пользователи утилиты потом расскажут) или перекодировать вводимые/выводимые строки на лету.

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

    Лучше исходники всегда писать в UTF8 а для строк использовать wchar_t.
    Тут и не только тут эта проблема уже обсуждалась не однократно. Например посмотрите эту ссылку: https://qna.habr.com/answer?answer_id=2278154#comm...
    Не смотрите, что там тема по Си - проблема та же самая и решения для Си и С++ будут похожие.
    Ответ написан
    Комментировать
  • Почему эта программа вычисляет факториал больших чисел неправильно?

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

    Думаю, больше толку было бы для оптимизации, если бы использовались SIMD инструкции, а не многопоточность.
    Есть оптимизированные библиотеки для длинной арифметики, проще всего было бы использовать какую-то подобную библиотеку, а не изобретать собственный велосипед. С использованием такой библиотеки задача была бы достаточно тривиальной.
    Ответ написан
    5 комментариев
  • Можно ли сделать раздельное туннелирование VPN для отдельных программ?

    @res2001
    Developer, ex-admin
    Добавьте маршруты до адресов discordа через ВПН. А остальное пускайте на шлюз по умолчанию.
    При подключении ВПН не должен переписывать шлюз по умолчанию.
    Останется только выяснить адреса дискорда. В этом могут помочь сервисы whois.
    Ответ написан
    Комментировать
  • Данные в таком случае будут хранится в стеке?

    @res2001
    Developer, ex-admin
    Если это определение внутри функции/метода - то Number будет лежать на стеке.
    Если вне функции/метода - в области глобальных данных.
    А вот данные на которые указывает Number могут лежать где угодно.
    Да, указатель может указывать и на данные на стеке или в глобальной области. В общем на любой выделенный блок памяти он может указывать. А в вашем примере даже и не на выделенный, только обращаться по такому указателю нельзя.
    Ответ написан
  • Как организовать свой интернет-магазин на NAS?

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

    @res2001
    Developer, ex-admin
    Если количество цифр фиксировано, то просто перечислите в формате scanf сразу их все.
    Если количество цифр может меняться, то ...
    Вводить как строку и потом парсить ее с помощью strtol, кода будет, конечно, больше, чем сейчас.
    Строку вводить в какой-то достаточно большой буфер длинной в 1 или 4 кб.
    При превышении буфера можно выдавать ошибку.
    Или ввод оформить в цикл, на случай, если буфер заполнится, а Enter пользователь еще не нажал. Выход из цикла по нахождению символа '/n' в буфере. В таком случае буфер можно делать меньше. Но тут возникает дополнительная проблема с неоконченным вводом, т.е. пользователь вводит число 123456 и допустим 123 прилетело в конец прошлого буфера, а 456 в начало следующего. Это надо будет решать в коде.

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

    @res2001
    Developer, ex-admin
    Можно запускать скрипт удаленно с помощью psexec или wmi. Предварительно надо будет настроить все удаленные станции, чтоб можно было это использовать.
    Это может быть простой батник, который убивает процесс и запускает повторно. Правда есть нюанс - удаленно скрипт можно запустить только с админскими правами, а приложение надо запускать с правами пользователя и в сеансе пользователя.
    Чтоб решить эту проблему может быть запуск можно сделать не на прямую, а например из задачи шедулера, которую удаленным скриптом дергать. Кстати утилита schtasks, с помощью которой можно управлять заданиями шедулера из ком.строки, умеет работать удаленно. Так что возможно даже psexec/wmi не понадобятся. Т.е. нужно написать локальный скрипт, который ищет нужный процесс, прибивает его и запускает повторно. Настроить в шедулере задачу с фиксированным именем с запуском этого скрипта и выключить эту задачу. Дальше на сервере при наступлении события просто дергаете schtasks, который будет удаленно принудительно одноразово стартовать настроенную задачу.
    Ответ написан
    5 комментариев