Ответы пользователя по тегу C
  • Почему возникает такая проблема с динамическим массивом (Язык Си)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ошибка возникает на моменте сдвига элементов. Как ее исправить?
    data = (Student*)realloc(data, count * sizeof(Student));
    
        for (int i = count; i > offset; i--)
        {
            data[i] = data[i - 1];
        }

    Этот код пишет за конец массива, потому что если в массиве count элементов, то последний имеет индекс count - 1. Этот цикл должен быть таким: for (int i = count - 1; i > offset; i--)
    Ответ написан
    Комментировать
  • Почему не работает функция fscanf?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    в функции main, почему то выводит мусор

    Значит дочитывает файл до конца и без ошибок конверсии. Такой формат: %32[^,] может записать до 33 байт (32 символа из файла + 0), что не влезет в такое поле: char title[32];. Если файл в кодировке utf-8, то байтов в полях может быть больше чем символов.
    Ответ написан
    Комментировать
  • Почему так читается текстовый файл?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему-то как я не стараюсь всё записывается только в sportsmens[i].full_name,

    Поскольку ты используешь fscanf, а поля в твоём файле разделены пробелами, формат fscanf должен включать в себя пробелы чтобы избавиться от разделителей. Кроме того, имеет смысл проверить, что setlocale возвращает не-NULL, иначе он не повлияет на десятичный разделитель (и %f не сможет прочитать число с плавающей точкой записанное как 12,12).
    Ответ написан
    4 комментария
  • Как переводить из двоичного числа - строки в десятичное число строку?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Но не получается

    Ну да, не получается, потому что ты не понял алгоритма по ссылке до конца, потому что его изложение оставляет желать лучшего.
    - zeroCounter как я понял нужен для реализации шага "Remove leading "0" from X'", но эта реализация неправильная. К тому же она находится вне цикла while ( X != "0" ).
    - for (b in bits of X) // msb to lsb говорит о том, что b должен пробегать двоичные цифры, от старшего разряда к младшему, в формуле R = 2*R + b фигурирует значение разряда, а не его индекс, как в твоём коде.

    R, как я понимаю, должна быть очередная десятичная цифра получающегося числа?

    Это верно. Очередной младший разряд.
    Ответ написан
    Комментировать
  • Почему возникает ошибка "Process finished with exit code 139"?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему возникает ошибка

    Из-за лишней звёздочки вот тут в функции input_array: scanf("%d", *(b+i));
    Но и дальше пораскидано граблей: input_array выделяет память (b = (int*) malloc(a * sizeof(int));) и даже пытается её возращать, но неправильным типом и main это значение не использует. А поэтому в main b как был NULL так и остаётся. По-хорошему надо как-то так:

    int * input_array(int a){
        int *b = (int*) malloc(a * sizeof(int));
        for (int i = 0; i < a; ++i) {
            printf("array[%d] = ", i);
            scanf(" %d", b+i);
        }
        return b;
    }


    int main() {
        ...
        printf("Введите длину массива:");
        scanf(" %d", &a);
        int *b = input_array(a);
        min = find_min(b, a);
        max = find_max(b,a);
        average = average_function(min, max);
        ...
    }
    Ответ написан
    Комментировать
  • Как найти количество вхождений строки в строку, используя regex?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как сделать, чтобы строка, которую ищем, задавалась через regex?

    в posix есть вот такой интерфейс, в конце мануала есть пример.
    Ответ написан
    Комментировать
  • Как в Си вывести в консоль без записи в буфер?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Если я использую printf("asd"), то весь текст в кавычках будет выведен на экран и записан в лог файл. Вот такая команда: './a.out > file.log'.

    Здесь несколько несуразностей: 1) printf в ./a.out > file.log не выведет ничего на экран, всё будет перенаправлено в файл. но 2) сам printf об этом ничего не знает. Он выводит данные в поток стандартного вывода, куда они перенаправляются потом -- не его дело. 3) оператор > перенаправляющий вывод -- это инструкция командной оболочке как запускать программу, к самой программе отношения не имеет.

    Есть ли какая другая команда вывода, которая будет текст выводить только в терминал, без записи в файл?

    Есть! ./a.out, без каких-либо изменений в коде.
    Ответ написан
    4 комментария
  • Как создать динамическую библиотеку, которая зависит от другой библиотеки?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    гугля, находил предложения с LD_LIBRARY_PATH=... . Но разве флаг -L при компиляции не служит той же самой цели?

    нет, не служит. -L говорит о том, где искать любые библиотеки во время линковки приложения. LD_LIBRARY_PATH говорит о том, где искать динамические библиотеки во время выполнения. Информация из -L со времени линковки нигде не сохраняется. Можно зашить в слинкованный бинарник пути к библиотекам, но это делается другими опциями (см. опцию линкера -rpath). Во время выполнения динамические библиотеки могут быть где угодно, не обязательно там, где они были во время линковки.

    Как создать динамическую библиотеку, которая зависит от другой библиотеки?

    вопрос, кстати, неправильный. Ты создал такую библиотеку. Если ты посмотришь в вывод readelf -d libwindow.so | grep NEEDED то там должна быть ссылка на libSDL. Твоя проблема в том, что сама libwindow.so не найдена.
    Ответ написан
    3 комментария
  • Как осуществить взаимодействие клиента и сервера на основе протокола TCP/IP?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Если у тебя посреди функции main сервера действительно стоит return x | y;, то она не может никогда вызвать send, а программа-сервер должна просто завершаться после расчёта НОД.

    А программа-клиент при этом будет получать ошибку из recv, но поскольку ты её не обрабатываешь, то дальше она будет пытаться выводить ответ из буфера в который не было ничего принято.

    не знаю, как правильно найти НОД в данном случае:

    в данном случае x и y нужно извлечь из принятой из сокета строки, математика дальше в порядке, вместо return x | y нужно просто использовать x | y в itoa. Res и всё что с ним связано можно выкинуть, поскольку оно всё равно никак не используется.

    Но вообще, конечно, из кода видно, что твоя проблема не с НОД и не с сетевым программированием, а с тем, что С/С++ ты, судя по всему, просто не знаешь. Учи основы, не жди халявы.
    Ответ написан
    Комментировать
  • Как работает выделение памяти malloc?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    char *str = malloc(0);
    Правильно ли я понимаю, что в str находится начало выделянно памяти на 0 байт


    Вот что говорит стандарт (c99, 7.20.3:1) о выделении 0 байт через malloc:

    If the size of the space requested is zero, the behavior is implementation-
    defined: either a null pointer is returned, or the behavior is as if the size were some
    nonzero value, except that the returned pointer shall not be used to access an object.


    Поскольку твоё обращение к этой памяти не вызывает SEGFAULT, то да, malloc вернул не NULL. Сколько байт реально было выделено зависит от реализации.

    а дальше идет запись символов в память, которая для нас не предназначалась?


    Да. Использовать эту память согласно стандарту нельзя.
    Ответ написан
    Комментировать
  • Как поставить пробел после запятой в строке?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В чём же проблема?
    for (int i = strlen(sentence); i >= pos; i--) {
        sentence[i + 1] = sentence[i];
        sentence[pos] = ' ';
      }

    Должно быть
    for (int i = strlen(sentence); i > pos; i--) {
        sentence[i + 1] = sentence[i];
      }
      sentence[pos + 1] = ' ';
    Ответ написан
    Комментировать
  • Зачем нужно выравнивание памяти? Точнее, почему процессор обращается 2 раза к невыравниным данным?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Для процессора x86 с word 32bit. Как будут выполняться fetch?
    Хочу ответ в таком формате.

    Что мешает взять спецификацию на процессор и почитать, например, раздел 5.3.6?

    почему процессор обращается 2 раза к невыравненным данным?

    Если посмотреть на схему i386 на первой же странице документа по ссылке выше, то можно увидеть, что шина адреса процессора имеет линии A2 - A31. Линий A0 и A1 тупо вообще нет, физически.
    Ответ написан
    Комментировать
  • Как передать двумерный массив функции?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как передать двумерный массив функции?

    https://qna.habr.com/answer?answer_id=513953#answe...
    Ответ написан
    Комментировать
  • Какие есть специфичные функции для glibc?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    с чем могут возникнуть проблемы

    Можно начать отсюда.
    Из моего опыта, самое часто всплывающее отличие glibc от других libc -- поддержка версионирования символов.
    Ответ написан
  • Как загрузить ядро тиа ELF через службы UEFI (gnu-efi)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Я пытаюсь загрузить 64-битное ядро по адресу 0x1000

    Я вижу в этом коде три проблемы:
    1. AllocatePages только возвращает адрес выделенной памяти по адресу в последнем параметре. Т.е. куда будут загружены сегменты ELF сказать нельзя и, соответственно, без динамической релокации этот ELF скорее всего работать не будет.
    2. Нет гарантии, что между блоками памяти выделенными через AllocatePages будет то же расстояние, что и между сегментами ELF, в то время как кодогенерация с флагом -fPIE вполне может считать это расснояние неизменным. Такой ELF нужно загружать в один большой блок памяти, сохраняя расстояние между сегментами.
    3. В следствие пункта 1 запуск ядра по адресу header.e_entry -- это прыжок в неизвестность.
    Ответ написан
    Комментировать
  • Как написать Netflow сенсор с нуля?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как мне модифицировать мою программу, чтобы она могла определять потоки и корректно отправлять их коллектору?

    Для этого тебе надо понять, что такое "потоки" о которых ты говоришь, где находится информация о принадлежности пакета потоку и как до неё добираться.

    Если ограничиться определением по ссылке, то тебе надо будет разбирать сырые пакеты до сетевого уровня, откидывать не-IP, из IP извлекать IP-протокол, адрес источника, адрес назначения и тип сервиса, для протоколов TCP и UDP дополнительно извлекать порт источника и порт назначения. Всё это довольно просто сделать самому вооружившись RFC по упомянутым протоколам. Также надо будет понять, что делать с фрагментированными IP-пакетами.
    Ответ написан
    Комментировать
  • Зачем нужен signed в Си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    по умолчанию int является signed

    А вот о char этого сказать нельзя, знаковость char зависит от реализации. Вдобавок, в стандарте есть следующая сноска (https://www.open-std.org/JTC1/SC22/WG14/www/docs/n... 6.2.5:15):
    Irrespective of the choice made, char is a separate type from the 
    other two and is not compatible with either.


    signed char -- это, пожалуй, единственное не вызывающее вопросов применение ключевого слова signed в C-коде написанном человеком. В остальных случаях роль signed -- чисто декоративная.
    Ответ написан
    Комментировать
  • Как сделать, чтобы printf() заменял -nan на любой заданный символ?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как сделать, чтобы вместо -nan печатался символ "-" ?

    Только добавив свою логику в свою программу, проверяющую значение на NaN и печатающую в зависимости от этого то или иное значение. С помощью стандартного printf -- никак.
    Ответ написан
    Комментировать
  • Указатели в языке Си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    почему программа завершилась? Вмешалась ОС? Но если так, то почему?

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

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

    Значение указателя ты поменять можешь, но это не то, что было написано в коде. В коде было написано поменять значение на которое указатель указывает. Поменять указатель было бы a = (int *)10;

    могу ли я указателю дать ссылку на конкретную ячейку в памяти?

    Можешь, но под ОС с виртуальной памятью это в большинстве случаев не имеет смысла. API в таких ОС обычно устроены так, что ты просишь выделить область памяти с заданными характеристиками, а ОС выполняет выделение и возвращает тебе адрес выделенного участка.

    получаю ошибку, ведь вряд ли адрес памяти у указателя хранится в виде 16-ричного целочисленного литерала.

    В памяти всё хранится как последовательность байтов. Любую последовательность байтов можно проинтерпретировать как указатель. Но чтобы компилятор С понял что ты имеешь в виду, ему надо явно сказать, что ты хочешь проинтерпретировать целое число как адрес: int *a = (int *)0x0061FF18;
    Ответ написан
    Комментировать
  • Почему inline функция не компилилируется?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему так происходит?

    Потому что стандарт С11 (9899:201x 6.7.4:7, черновик доступен тут) говорит следующее про спецификатор inline:

    Any function with internal linkage can be an inline function. For a function
    with external linkage, the following restrictions apply: If a function is declared
    with an inline function specifier, then it shall also be defined in the same translation
    unit. If all of the file scope declarations for a function in a translation unit include
    the inline function specifier without extern, then the definition in that translation
    unit is an inline definition. An inline definition does not provide an external
    definition for the function, and does not forbid an external definition in another
    translation unit. An inline definition provides an alternative to an external
    definition, which a translator may use to implement any call to the function
    in the same translation unit. It is unspecified whether a call to the function uses
    the inline definition or the external definition.

    Самое главное тут -- в середине: инлайн-реализация не предоставляет и не запрещает реализацию со внешней линковкой, и в последнем предложении: транслятор волен сам выбирать, какую реализацию функции использовать -- инлайновую или со внешней линковкой.
    Поскольку ты написал так:
    inline void some_inline_func(uint32_t num)
    {
        . . .
    }

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

    Вариантов решения этой проблемы примерно 3:
    - определить функцию следующим образом:
    extern inline void some_inline_func(uint32_t num)
    {
        . . .
    }

    Такая функция будет доступна из других единиц трансляции.

    - либо определить функцию следующим образом:
    static inline void some_inline_func(uint32_t num)
    {
        . . .
    }

    Такая функция будет доступна только для данной единицы трансляции.

    - оставить в этом исходнике всё как есть, а в каком-нибудь другом определить следующую функцию:
    void some_inline_func(uint32_t num)
    {
        . . .
    }

    Это самый дурацкий вариант, поскольку эти две реализации могут не совпадать и в зависимости от выбора транслятора ты можешь получить разное поведение.
    Ответ написан
    Комментировать