Ответы пользователя по тегу C
  • Почему scanf считывает значение только первой переменной?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Если вам нужен ввод целых чисел, то читайте их в целые переменные через %d. Еще, scanf возвращает количество прочитанных значений. Т.е. сравнивать надо с тройкой, а не единицей.

    Еще одна проблема: возможно, из-за настроек локализации, оно ждет десятичные запятые, а не точки. Попробуйте ввести "1,0 2,0 3,0" или "1 2 3".

    И вообще весь ваш сценарий - это комбинация ошибок в пером и втором абзаце. Из за точек вместо запятых оно читает только первую переменную сначала, видит, что ввело 1 переменную и завершает цикл. При вооде "1 2 3" оно читает все переменные, но из-за ошибки в проверке (вы же хотите, чтобы одна прочиталась) читает опять. При повтороном вводе "1.0 2.0 3.0" оно читает только первую переменную и завершается. При этом в b и c остались значения от прошлого ввода.
    Ответ написан
    2 комментария
  • Почему при передаче имени файла как аргумент функции я не могу его открыть?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Смотрите внимателно на тип параметра в функции. Это char. Один символ, или число от 0 до 255. А вы потом рабоатете с ним, как со строкой (указателем на char). Вы передаете это число от 0 до 255 в strcat, он пытается записать что-то по адресу от 0 до 255 и, ожидаемо, падает.

    Поставьте там звездочку.

    Еще комментарии: ".txt\0". Терминирующий \0 ставить не надо, "" уже его ставит само. 10 символов на filename может не хватить.
    Ответ написан
    3 комментария
  • Почему вначале все работает, а потом нет?

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

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Код выглядит правильно, только массив объявлен на 15 элементов, а цикл до 16 идет. И, возможно, надо 0 на 1 в проверке поменять. "Нечетные позиции", по человечески - это первая, третье и т.д. Но им соответствуют четные индексы 0, 2...

    Edit: А еще в коде стоит точка с запятой после for, из-за чего цикл оказывается пустым, а вводится только один элемент (и тот за границей массива):
    for (i=0; i<16; i++); // <----------
    scanf("%d", &A[i]);
    Ответ написан
  • Как выделить память в другой функции, передавая pointer через аргументы?

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

    Если уж очень надо через аргументы, то передавайте указатель на указатель:
    static void update_callback(char **ptr)
    {
        *ptr = (char *)malloc(sizeof(char) * TEST_STR_SIZE + 1);
    ...


    P.s. В вашем коде утечка памяти. Вы выделяете память, потом единственный указатель на эту память переписываете указателем на TEST_STR.
    Ответ написан
    6 комментариев
  • Как не обрезать стркоу после \0?

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Это не разбиение на части, а разбор строки.
    Вычтите из второго символа '0'. Ведь символы в C - это числа, просто каждому числу назначен символ по кодам ascii. Буквы английского алфавита и цифры идут по порядку в этих кодах. Поэтому при вычитании символа 0 вы получите численное значение цифры.

    Для первой переменной просто скопируйте первый символ.
    Ответ написан
    Комментировать
  • Почему происходит сегфолт?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Комментарии в коде вроде //4 значение по адресу однозначно говорят, в чем проблема. Вы хотите работать с четверкой чисел, а в строке их у вас всего 2.
    Ответ написан
  • Подсчет чисел в массиве, в языке C?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Человек под номером i (c 0) идет в команду i % K, где K - количество команд (опять же, нумерация с 0).

    Вам надо лишь в цикле пройтись по всем числам и прибавить их в соответствующую ячейку ответа.
    Ответ написан
    Комментировать
  • Быстро ли мое решение?

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

    Ваш текущий вариант вносит дополнительное разименовывание указателя на каждое число.
    Вариант с memcpy внесет дополнительное копирование, что помедленнее разыменовывания указателя по идее.

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

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

    Вы же менянте местами значения int, значит временная переменная tmp должна быть int, а указатели надо разименовывать.
    Ответ написан
    Комментировать
  • Как посчитать количество разных букв в массиве строк?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Можно считать, например самые левые вхождения каждого символа. Для этого пройдитесь по массиву циклом, а внутри вторым циклом проверьте, а есть ли такой же символ левее данной позиции. Если вы такого повторения в цикле не нашли, то надо прибавить 1 к ответу.

    Второй вариант - отсортировать символы. Там уже проще подсчитать все символы - это 1 + сколько разных соседей в отсортированном массиве. Это быстрее, если использовать быструю сортировку.

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

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Можно выводить в stderr через fprintf. Тогда перенаправление в файл запишет туда только то, что выведено в stdout через printf.

    А так /a.out > file.log просто перенаправляет stdout в файл и все, что будет туда выведено, будет записано в файл самой системой. Ваша программа не знает, куда там система будет содержимое потока выводить - в консоль или в файл. Никак на это повлиять вы не сможете. Остается только писать в другой поток, например stderr.
    Ответ написан
  • Какими функциями заменить array_diff() в Си?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Руками. Если лень писать свою хеш таблицу, то можно и совсем в тупую. Итерируйтесь по списку a. Внутри итерируйтесь по списку b и, если нашли там элемент, то удаляйте из a. Иначе переходите к следующему элементу.

    Более продвинутый вариант - отсортировать список b и искать там каждый элемент из a бинарным поиском.

    Удобный трюк для удаления элементов из массива - хранить индекс первого не занятого элемента. Тогда получается что-то вроде этого:
    int empty_pos = 0;
    for (int i = 0; i < n; ++i) {
      if (!ShouldDelete(a[i], b)) {
        a[empty_pos++] = a[i];
      }
    }
    n = empty_pos;
    Ответ написан
    3 комментария
  • Почему при создании динамической строки игнорируется нулевой индекс?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Там же число, которое читается через scanf("%d", &N); в первой строке.
    Ответ написан
  • Какая сложность у такого цикла for?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Так.
    Ответ написан
    Комментировать
  • Как исправить ошибку "unsorted double linked list corrupted"?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Это проблема работы с памятью. Вы там освобождаете память из-под str перед тем, как попросить gmp заполнить эту строку данными:
    free(str);
    mpz_get_str (str,10 , mul);


    gmp пишет данные туда, где была строка. Но в это место нельзя писать после free. Иногда так получается. что менеджер памяти хранит там какие-то свои данные, которые вы портите и потом получаете об этом ошибку. Память может быть возвращена системе, и тогда программа может упасть вообще при попытке записать туда что-то. Или ничего заметного может не произойти вообще.

    Как это часто бывает с ошибками работы с памятью, любая мелочь, вроде фазы луны или лишнего отладочного вывода где-то, может изменить то, как эта испорченная память используется и ошибка может не вызвать падения.
    Ответ написан
    Комментировать
  • Выдает то signal: illegal instruction core dumped то stack smashing detected terminated. Как исправить?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    Строки ваши подлиннее сделайте. Вы там по 2 символа для каждой выделяете. Но надо еще место для закрывающего 0 оставить. Поэтому, если пользователь вводит более 1 символа, происходит переполнение стека.
    Ответ написан
    Комментировать
  • Как считать строку в nasm?

    wataru
    @wataru
    Разработчик на С++, экс-олимпиадник.
    В итоге все делается через биос. Вам надо будет писать какие-то данные в I/O порты, использовать прерывания, чтобы заставить биос прочитать нажатия на кнопки и поместить данные в какую-то вашу память.
    Ответ написан
    Комментировать
  • Как реализовать завершение игры "Жизнь" на Си?

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

    Можно запоминать предыдущие поля. Хотя бы в виде хешей для экономия памяти. Чтобы из-за коллизии не заврешаться раньше времени, можно считать несколько принципиально разных хешей (допустим, sha256 и какой-то полиномиальный хеш), и плюс брать "слепок" от поля (какие-то 256 разбросанных по полю клеток).

    Или, если поле не большое, то можно вместе с хешом хранить все поле. Если где-то хеши совпали, то дальше нужнол сравнивать уже поля целиком поклеточно.
    Ответ написан
    1 комментарий