Ответы пользователя по тегу C
  • Как сделать layer 2 dissector wireshark?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как передать в диссектор кадр целиком? Чтобы оно не выделяло Ethernet заголовок при парсинге пакета?

    Зарегистрироваться не на "ethertype" а на "eth" или на "frame"?
    Ответ написан
    Комментировать
  • Как правильно использовать gettext в C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    man setlocale предлагает
    int main (int argc, char * const argv[], char * const argp[])
    {
        setlocale(LC_ALL, "");
        ...
    }

    совместно с переменной окружения LC_ALL или LANG.
    Ответ написан
  • Проблемы с фукнцией atoi?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Maqsat Batyrqul: atoi -- функция из стандартной библиотеки С, она работает с С-строками. С-строка это последовательность символов в памяти, заканчивающаяся символом конца строки -- символом с кодом 0.
    Написав *temp = s[i], или что то же самое temp[0] = s[i] вы скопировали i-й символ из строки s на первое место в строке temp. Проблема изначального кода в том, что указатель temp не инициализирован, а значит может указывать в любое место в памяти. Т.е. вы скопировали символ в любое место в памяти. Мест в памяти в которые можно записывать существенно меньше, чем мест, в которые записывать нельзя. По счастливому стечению обстоятельств temp в вашей программе указывал в место, в которое записывать нельзя, в результате чего вы видели Segmentation fault при попытке записать туда.
    В отличие от char *temp, запись char temp[2] определяет не указатель, а массив. Массив -- это непрерывный участок памяти. Если массив не константный, в него можно писать. Имя массива в большинстве случаев ведёт себя как указатель на первый элемент массива. Инициализировав массив нулями вы получили два нулевых символа в памяти, в которые можно писать. В цикле вы заменяете первый символ в этом массиве на i-й символ из массива s, второй символ остаётся неизменным -- символом с кодом 0, т.е. символом конца строки. Т.е. массив temp в цикле представляет собой С-строку единичной длины, которую можно передавать на вход atoi.
    Ответ написан
    Комментировать
  • Как пользоваться stdint.h?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    uint_fast64_t number = 184467440737095511615;

    В этом месте нужно написать
    uint_fast64_t number = UINT64_C(184467440737095511615);

    Даже присваиваться не хочет, как такое выводить тоже не понятно.

    В inttypes.h есть макросы для форматирования типов из stdint.h в printf, вам нужен PRIuFAST64:
    printf("%"PRIuFAST64"\n", number);

    Ну и да, для криптографии этих типов скорее всего будет мало. Порекламирую https://gmplib.org/ для разнообразия.
    Ответ написан
    Комментировать
  • Где исходный код system call open()?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В fs/open.c нет функции open()

    Да вот же она: lxr.free-electrons.com/source/fs/open.c#L1049

    SYSCALL_DEFINEx -- это реализация системного вызова с x параметрами, первое слово в скобках -- это название вызова, дальше -- x пар: тип параметра и имя параметра.
    Ответ написан
  • Почему это моветон?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Алексей: Евгений Шатунов:
    Люди умеющие гуглить, но не понимающие, о чём речь, дают ответы! Каждый день на тостере!
    Они могут нагуглить статью, в которой говорится примерно о том же, о чём задан вопрос, но, увы, не вполне.
    И ни в статье, ни в ответах так и не появляется правильного ответа.
    А правильный ответ -- во второй, неочевидной части пункта стандарта, описывающего выражения (C89: 3.3:2, C99: 6.5:2):

    Between the previous and next sequence point an object shall have its stored value
    modified at most once by the evaluation of an expression. Furthermore, the prior value
    shall be read only to determine the value to be stored.


    Т.е. если объект модифицируется, то читать его можно с единственной целью -- для вычисления значения, которое будет в него записано. Код a[i] = i++; читает значение изменяемой переменной i с другой целью: доступ к элементу массива по индексу, результат которого не влияет на конечное значение i -- и этого достаточно, чтобы такой код попадал в категорию UB.
    Ответ написан
    7 комментариев
  • Почему при прерывании работы сервера (Ctrl + C) recv не возвращает ошибку?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Возможно серветный сокет закрывается нормально, а recv возвращает 0. Из man recv:
    These calls return the number of bytes received, or -1 if an error occurred. The return value will be 0 when the peer has performed an orderly shutdown.

    Вообще вы очень лихо печатаете результат из буфера заполненного recv: нет никакой гарантии, что принято будет ровно столько, сколько отправит send, и завершающего символа с кодом 0 может не оказаться в буфере. Правильнее было бы сделать хотя бы так:
    ssize_t recvd = recv(ClientSocket, buffer, MESSAGE_MAXLEN, 0);
      if (recvd != SOCKET_ERROR)
      {
        // recv не возвращает ошибку
        printf("server response: %.*s\n", recvd, buffer);  // напечатает только то, что было принято
      }
      else
      {
        error = WSAGetLastError();
        printf("recv failed: %d\n", error);
      }
    Ответ написан
  • Как узнать размер текстового файла в байтах?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Ответ написан
    Комментировать
  • Некорректное вычисление?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    выдают одинаково верный результат

    одинаково верный результат для java, потому что порядок вычисления значения выражений в java определён строго для любого выражения, см. https://docs.oracle.com/javase/specs/jls/se7/html/...

    С++ -- это другой язык, на нём можно написать выражение вроде вашего, значение которого не определено стандартом и может варьироваться в зависимости от компилятора, опций оптимизации и фазы луны. См. https://ru.wikipedia.org/wiki/%D0%A2%D0%BE%D1%87%D...
    Ответ написан
    Комментировать
  • Как правильно читать спецификацию (C/C++)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ответы в которых люди дают развернутые ответы и цитируют стандарт языка

    Я так довольно часто делаю.

    Люди, которые знакомы с ней, непосредственно брали в руки документ и читали его от корки до корки? Или же это происходило в процесс практики

    И так и так. Вообще полезно начать с того, чтобы просто пролистать стандарт, чтобы понять, о чём там вообще написано, и где искать ответы на возникающие вопросы.
    А дальше можно просто искать ответы на все подряд вопросы относительно языка, как свои, так и чужие.
    Ответ написан
    Комментировать
  • Можно ли юзать C библиотеки не как динамические?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    По идее я должен взять исходники библиотеки и прямо из Go указать пути к исходникам

    По идее вам надо просто заменить линковку с динамическими библиотеками (.so) линковкой с соответствующими статическими библиотеками (.a). Исходники не нужны.

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

    Некоторые библиотеки могут иметь некоторые проблемы при таком использовании, например: https://bugzilla.gnome.org/show_bug.cgi?id=768215#c16
    Ответ написан
    2 комментария
  • Как избавиться от переполнения?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    где-то читал, что переполнения беззнаковых целых быть не должно.

    Нет никакой магии в беззнаковых целых, максимальное представимое число -- 2^(количество бит)-1, от больших чисел остаётся остаток по модулю 2^(количество бит). Это поведение описано стандартами языка C.
    Ответ написан
    Комментировать
  • Pure C. Где исходные коды стандартной библиотеки Си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Неужели СТАНДАРТНАЯ БИБЛИОТЕКА (которая почти часть языка) это какой-то секрет?

    Вовсе нет:
    glibc: https://sourceware.org/git/?p=glibc.git;a=tree
    musl: git.musl-libc.org/cgit/musl/tree
    uclibc-ng: repo.or.cz/uclibc-ng.git/tree
    newlib: https://sourceware.org/git/gitweb.cgi?p=newlib-cyg...

    Просто обычному человеку эти исходники почти никогда не нужны.
    Ответ написан
    1 комментарий
  • Как скачать n байтов удалённого файла на ANSI C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    size_t read_from_url(const char *url, char *buf, size_t sz)
    {
        char *cmd = malloc(strlen(url) + 13);
        FILE *f;
        size_t off = 0;
    
        sprintf(cmd, "wget -O - '%s'", url);
        f = popen(cmd, "r");
        free(cmd);
    
        while (sz) {
            size_t rd = fread(buf + off, 1, sz, f);
    
            if (rd == 0)
                break;
            off += rd;
            sz -= rd;
        }
        pclose(f);
        return off;
    }
    Ответ написан
    Комментировать
  • Как хранить результат вызова системной команды?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    man popen
    #include <stdio.h>
    
    int main()
    {
        int n;
        FILE *f = popen("grep -c \"a\" < 1.txt", "r");
        fscanf(f, "%d", &n);
        pclose(f);
        ...
    }
    Ответ написан
    2 комментария
  • Код C, который не будет работать в C++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Вот пример с двумя файлами, который компилируется и как С и как С++, но линкуется только как С. Различие между языками в наличии в С tentative definition:
    Файл a.c:
    int i;
    
    int main()
    {
        i = 1;
        return 0;
    }


    файл b.c:
    int i;
    
    int f(void)
    {
        i = 1;
        return 0;
    }


    $ gcc -std=c89 a.c b.c -o a
    $ gcc -std=c99 a.c b.c -o a
    $ gcc -std=c11 a.c b.c -o a
    $ g++ a.c b.c -o a
    /tmp/cc8AfU2T.o:(.bss+0x0): multiple definition of `i'
    /tmp/ccBOJ29v.o:(.bss+0x0): first defined here
    collect2: error: ld returned 1 exit status
    Ответ написан
    Комментировать
  • Почему возникает ошибка incompatible types when assigning to type?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    table = fizz(table);

    Что сделать-то хотел?
    Если проинициализировать массив значением которое вернула fizz, нужно было просто проинициализировать его в этой функции.
    Если поменять область памяти на которую указывает table, то нужно было сделать table указателем.

    Почему при передаче table в fizz struct Item[100] преобразуется в struct Item *table, а при присваивании - нет?

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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Используя TCP/IP -- никак. Указывайте длину данных в своём заголовке на сервере, а на клиенте получайте заголовок и читайте столько данных, сколько там записано.
    Ответ написан
    Комментировать
  • Есть ли в области системного программирования такие задачи, для которых целесообразно только использование ассемблера?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В области системного программирования гораздо чаще приходится читать ассемблер, чем писать на нём.
    Ответ написан
    Комментировать