Задать вопрос
  • Почему fopen устанавливает ошибку Invalid argument в errno при fopen в режиме r+ после w и fopen в режиме w+ после r?

    @res2001
    Qubc, Не то. Буквально errno = 0;
    Когда pFile уже закрыт, то вызывать для него clearerr - вообще смысла нет - он вернет ошибку. И clearerr сбрасывает флаги ошибок файла, а не errno.
  • Как лучше вносить изменения в стороннюю библиотеку С?

    @res2001
    kriptonus, А вы на линуксе собираетесь libmodbus использовать?
  • Как лучше вносить изменения в стороннюю библиотеку С?

    @res2001
    kriptonus, Т.е. вам нужно адаптировать библиотеку под железо. Обычно в таких случаях в библиотеках выделяют уровень абстракции железа (HAL или OSAL обычно называется). Часто он идет как отдельная низкоуровневая библиотека в зависимостях основной библиотеки. Как правило это достаточно не большой API, который надо реализовать и который будет использовать библиотека верхнего уровня. Часто можно взять уже готовые похожие реализации и адаптировать их под себя.
    Не знаю, есть ли в libmodbus свой HAL или получится с CTS. На сколько знаю, CTS часто используют для целей управления потоком приема/передачи в полудуплексном RS485.
  • Как лучше вносить изменения в стороннюю библиотеку С?

    @res2001
    kriptonus,
    переключать преобразователь в режим приема/передачи

    Преобразователь это же ведомое устройство в modbus? А ваша программа, видимо выступает как контроллер?
    Тогда вы должны с помощью библиотеки отправить на ведомое устройство некий пакет с конфигурацией. Я не в курсе, как там это в modbus конкретно работает, не имел с ним дела.
    Универсальная библиотека в принципе не может обеспечить работу со всей массой устройств, поддерживающих modbus. Библиотека, видимо, реализует только низкоуровневый протокол обмена, который описан в каком-то стандарте. А верхний уровень вы должны реализовать в вашем приложении. Для этого не нужно изменять библиотеку.

    Начните с изучения примеров к библиотеке (скачайте исходники, там есть тесты, их можно использовать в качестве примеров работы с библиотекой. Дальше - документация к библиотеке. Если захотите понять глубже, смотрите документацию на modbus.
  • Как и возможно ли сопоставить данные из одной таблицы .xlsx с данными из нескольких тысяч .xlsx?

    @res2001
    наименование столбцов не однообразны

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

    Ексел поддерживает встроенные скрипты на VBA, так что поиск по другим таблицам можно реализовать скриптом.
    Или настроить связи с другими таблицами. Но связи придется, видимо, делать вручную, а это несколько тысяч связей ...
  • Почему поведение fscanf ( stdin, "%c", &c ) различается при чтении EOF в msvc и gcc?

    @res2001
    Qubc, Кстати, есть еще одно отличие - в возвращаемых значениях.
    В версии MSVC при Ctrl-Z fscanf возвращает 0, а в gcc - -1.

    Ctrl-Z - это не настоящий EOF, в интернетах называют его "мягкий EOF".
    И он не вызывает закрытие потока, как должно быть при настоящем EOF, после которого любое последующее чтение должно вызывать ошибку.

    Вы какой gcc использовали? Дело ведь происходит под виндой.
    Я потестил на mingw-w64, поведение такое же как вы описываете.
    Но mingw использует стандартную библиотеку от MSVC. Так что есть вероятность, что в обоих случаях виновата микрософт :) Видимо просто разные версии стандартной библиотеки.
    Посмотрел по зависимостям исполняемого файла. В версии от gcc похоже используется fscanf из msvcrt.dll, а в версии от msvc эта библиотека не используется, похоже там вместо fscanf вызывается что-то другое, т.к. символа fscanf я в зависимостях не обнаружил. Но может быть просто плохо искал :)
  • Почему поведение fscanf ( stdin, "%c", &c ) различается при чтении EOF в msvc и gcc?

    @res2001
    Ctrl-Z не вызывает закрытие потока.
    Ctrl-Z - это обычный символ с кодом 26, просто обрабатывается специфически, обработка, видимо, зашита в стандартной библиотеке.
  • Почему поведение fscanf ( stdin, "%c", &c ) различается при чтении EOF в msvc и gcc?

    @res2001
    Детали реализации :)
    Не уверен, что поведение как-то стандартизовано.
    В линуксе, например, совсем другое поведение в терминале на Ctrl-Z - процесс уходит в спячку.
  • Почему вылетает исключение при удалении объекта?

    @res2001
    Dyikot,
    если не использовать интерфейс то ошибки нету

    Ну да, точно! Вы нашли ошибку.
    У вас же указатель приводится к типу интерфейса, а указатель на интерфейс не обязан совпадать по значению с указателем на реальный объект.
    Удаляйте items не внутри UseContainer, а там же где его создаете. При выделении памяти сохраняйте оригинальный указатель (на объект, а не на интерфейс) и его используйте в delete.
    Или смотрите ответ maaGames
  • Как через cmd закрыть процесс по названию загловка в win 2019?

    @res2001
    metalexs, taskkill вполне рабочий вариант. Но фиг знает как там фильтровать по WINDOWTITLE, состоящему из нескольких слов и т.п.

    Но можно делать по другому, фильтровать в tasklist по IMAGENAME (название исполняемого файла) с ключом /v (будет выводить и WINDOWTITLE), а затем в конвеере навешивать фильтр с помощью findstr:
    tasklist /FO table /V /FI "IMAGENAME eq prog.exe" | findstr "Window title"

    Всю эту конструкцию завернуть в цикл for /f, чтоб вытащить PID процесса и уже по PIDу убивать процесс с помощью taskkill.
  • Почему вылетает исключение при удалении объекта?

    @res2001
    Dyikot, Похоже на то, что у вас где-то выход за пределы выделенной памяти, что вызывает изменение указателя items на стеке. Сам код UseContainer выглядит вполне безобидным в этом плане, так что ошибка где-то глубже, внутри вызовов, используемых в UseContainer.

    Запустите под отладчиком, поставьте точку останова в начале UseContainer и выполняйте по шагам, не заходя в глубину. После каждого шага, контролируйте значение items. Когда оно изменится - значит выход за пределы был в предыдущем вызове.
    Следующий этап - ставите точку останова внутри "предыдущего" вызова и все повторяете снова.
    Возможно так придется делать несколько раз, с каждым шагом погружаясь глубже по стеку вызовов.
    В итоге найдете участок кода, где происходит выход за пределы памяти, устраняете ошибку. Профит.

    PS: Друзья - это зло, попытайтесь избавится от использования функций и классов друзей. В вашем случае это не нужно.
  • Вызов функции, экспортируемой из EXE. Как это сделать нормально?

    @res2001
    hard2018, RPC - это лишь обобщающее название технологии. Подходов и реализаций RPC много. Так что вы не можете просто "вызвать" через RPC, нужно выбрать конкретный механизм RPC, поддерживаемый ОС или сторонними библиотеками и его использовать в своем приложении. Кроме того в RPC 2 стороны взаимодействия и обе стороны должны явно использовать механизм RPC.
    Тот же COM имеет в своем составе DCOM, который является RPC механизмом.
    Можно на сокетах сделать свой собственный RPC.
    Этим список не ограничивается.
    https://ru.wikipedia.org/wiki/%D0%A3%D0%B4%D0%B0%D...
    https://learn.microsoft.com/en-us/windows/win32/Rp...

    RPC подразумевает передачу данных по сети. IPC - то же самое, но в рамках одного компьютера без выхода в сеть.
  • Вызов функции, экспортируемой из EXE. Как это сделать нормально?

    @res2001
    У вас это реализовано или нет? Что за модуль?

    Функции экспортируемые из EXE можно вызывать только в DLL, используемым этим EXE. Например, EXE грузит плагины, содержащиеся в DLL, и плагины могут вызывать какие-то функции API, предоставляемые самим EXE. Другие процессы не могут вызывать такие функции.

    Другой вариант: для передачи выводимых в консоль данных используете любой удобный механизм IPC, начиная файлов или именованных каналов до создания COM объекта.
  • Почему strcat перезаписывает переменные?

    @res2001
    Andrei1penguin1, Так же.
    Но этого не достаточно. Нужно каждый раз контролировать, чтоб буфер не переполнился.

    В той форме, что вы используете scanf нет контроля буфера за переполнением (функция не знает размер буфера). Можно использовать модификатор длины scanf("%100s", str)
    Но лучше использовать форму: scanf_s("%s", str, sizeof(str));
    scanf возвращает количество считанных (и записанных по указанному адресу) байт.
    Для справки: https://en.cppreference.com/w/c/io/fscanf
    С strcat можно контролировать переполнение "вручную" или использовать более защищенный вариант: strcat_s. https://en.cppreference.com/w/c/string/byte/strcat

    Вообще все строковые функции стандартной библиотеки имеют защищенные аналоги с суффиксом _s, которые и рекомендованы сейчас к использованию. Эти защищенные аналоги контролируют переполнение буфера, но работают немного медленнее из-за дополнительных проверок.

    Рекомендую использовать буфер не в 100 символов, а скажем в 1024 или еще больше.

    Если входная строка будет достаточно длинная, то любой буфер может переполнится.
    В этом случае нужно либо завершать программу с ошибкой или переходить на использование динамической памяти - т.е. при переполнении перевыделяем буфер большей длинны и продолжаем процесс. Но и динамическая память может кончится, только это произойдет позже :-)

    Вот это
    strcpy(&word, "");
    Можно заменить на word[0] = 0; с тем же результатом, в случае, когда у вас word будет массивом символов.

    В качестве оптимизации. Гораздо быстрее читать не по одному символу, а сразу в большой отдельный буфер и затем парсить этот буфер посимвольно. Код, конечно, усложнится, но работать будет быстрее. Стоит этим заниматься только если производительность для вас критична и только после того, как отладите "базовый" алгоритм.
  • Терминальный доступ к windows серверу без RDP - какими программами можно реализовать?

    @res2001
    kolabaister,
    Поверьте на слово

    В наше время даже английским джентльменам на слово не верят.

    Такого же качества продукт, как RDP, есть только у Citrix (у Citrix даже может быть и лучше), все остальное - жалкое поделье для других задач. Но Citrix не раздает его бесплатно.

    Что с ВПН совсем ни как? Можно ВПН пустить и по TCP и по стандартным портам (443).
    ssh работает? Можно через промежуточный ssh сервер настроить перенаправление портов через ssh. Будет такой себе ssh ВПН для одного порта.
    Или завернуть трафик в SSL тунель.
  • Почему не подключается OpenVPN?

    @res2001
    На сервере в логах тишина, как будто никто и не пытается подключиться.

    Тут больше интересно, что в логах у клиента, и хотелось бы увидеть чуть больше клиентского лога.
    Видимо, все таки трафик где-то блокируется. Проверяйте еще раз фаерволы. Попробуйте выключить все доступные вам фаерволы на пути следования пакетов. Можно попробовать сменить порт ВПН на какой-нибудь стандартный TCP (tcp/443 например).
  • Как узнать размер незаполненного массива в c++?

    @res2001
    Dmitrii, Мой пост больше для автора вопроса, на подумать. Он ищет универсальных решений и ему тут рады предлагать. Но реальность такая как я ее описал.

    strlen и "сырые" строки работают по принципу описанному во втором абзаце моего поста. Все функции работающие с сырыми строками знают, что внутри строки не может быть нулевого символа - это гарантируется алгоритмически.
    В некоторых случаях алгоритмически принимаемые значения никогда не используют какие-то биты. Эти биты можно использовать как признак отсутствия значения. Опять же - это вариант из второго абзаца.

    Хранить длину в первом элементе - то же самое, что хранить количество заполненных элементов (третий абзац). И не важно где именно вы храните количество заполненных элементов. Я бы не стал смешивать сущности.

    Большинство из предложенных вариантов может быть сведено к двум вышеперечисленным.

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

    @res2001
    А почему INT_MAX, а не INT_MIN, например, или любое другое значение?
    Во встроенных стандртных типах данных нет значений обозначающих "отсутствие значения". Любые значения являются "нормальными" для типа. Даже когда вы объявляете переменную без инициализации, она будет иметь какое-то значение, да это значение мусорное или случайное, но оно вполне "нормальное". Даже если рассмотреть float или double - там есть значения NaN и Inf, но и эти значения "нормальные" - они могут появляться в ходе обычных арифметических вычислений и их нельзя интерпретировать как "отсутствие значения".

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

    Наиболее универсальный вариант - хранить отдельно размер массива и количество заполненных элементов. Например, так происходит в std::vector, и думаю что в std::string примерно так же.
    Но это работает только для случая, когда все не используемые элементы лежать в конце массива. Этот подход не подойдет, когда не используемые элементы могут быть в произвольной позиции.
  • Как максимально очистить диск C?

    @res2001
    Krenicc, Кстати, стандартный виндовый менеджер очистки дисков очень не плохо справляется со своей работой. Рекомендую к использованию.