Задать вопрос
Ответы пользователя по тегу C
  • "undefined reference to" при линковке, что делать?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Хотелось бы скинуть на русском или на английском но увы, у меня линковщик почему-то говорит на украинском

    export LANG=C в консоли где выполняется линковка должен решить эту проблему.

    невизначене посилання __stack_chk_fail_local

    можно компилировать исходник на C с ключами -fno-stack-protector -fstack-check=no чтобы компилятор не вставлял проверки и вызовы этой функции. См.
    Ответ написан
    Комментировать
  • Как сделать или как работает listen localhost?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    я думаю что наверное надо делать bind на 127.0.0.1, но так ли это?

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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Если по логике 33/8=4

    Если логика математическая, то 33/8 = 4 1/8. И эту одну восьмую тоже надо где-то хранить.
    Ответ написан
    2 комментария
  • Ошибка при чтении бинарного файла?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    fwrite(array, sizeof(int),array_quantity,in);
    ...
        while((num=fgetc(in))!=EOF){
          //  queue_push(&q,num);
            printf("%i ",num);
        }


    в начале я добавляю числа 1 2 3 (пример) а из файла получаю 1000 2000 3000
    В чем дело?

    А тебя не смущает, что записываешь в файл ты array_quantity элементов размером sizeof(int) каждый, а читаешь из файла посимвольно?
    Ответ написан
  • Как прочитать заголовок PCAP пакета c/c++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    IP адреса Source и Destination выводятся одинаковыми

    Из man inet_ntoa:

    The string is returned in a statically allocated buffer,
    which subsequent calls will overwrite.


    С вот таким изменением твой код у меня работает как ожидалось:
    printf("src address: %s ",  inet_ntoa(ip->ip_src));
    printf("dest address: %s\n",  inet_ntoa(ip->ip_dst));


    Подозреваю, что совсем левые IP могут лезть из не-IP кадров. Проверяй поле протокола в ethernet заголовке перед тем как начинать разбор IP-заголовка.
    Ответ написан
  • Насколько хорошим решением является использование pthread_kill для возобновления работы потоков?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Насколько хорошим решением является использование сигналов для выведения потоков из спящего режима, и стоит ли для этого использовать ...

    Является решением, но не самым традиционным. Насколько хорошим -- зависит от модели совместной работы потоков/того как разделяются данные между ними. Не хватает контекста для ответа.
    Ответ написан
  • Некорректно работает пользовательская библиотека.Что делать?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    main.c:5: undefined reference to `push'

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

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

    Как-то так:

    #include <stddef.h>
    #include <stdio.h>
    
    typedef int T;
    
    void rotate(T *p, size_t m, size_t n, size_t (*turn)(size_t m, size_t n, size_t idx))
    {
            size_t i, j, k;
    
            for (i = 0; i < m * n; ++i) {
                    T tmp0, tmp1;
    
                    for (j = 0; j < i; ++j) {
                            for (k = turn(m, n, j); k != i && k != j; k = turn(m, n, k)) {
                            }
                            if (k == i)
                                    break;
                    }
                    if (j < i)
                            continue;
    
                    tmp0 = p[i];
                    for (j = turn(m, n, i); ; j = turn(m, n, j)) {
                            tmp1 = p[j];
                            p[j] = tmp0;
                            tmp0 = tmp1;
                            if (j == i)
                                    break;
                    }
            }
    }
    
    void dump(size_t m, size_t n, T p[m][n])
    {
            size_t i, j;
    
            for (i = 0; i < m; ++i)
                    for (j = 0; j < n; ++j)
                            printf("%d%s", p[i][j], j == n - 1 ? "\n" : ", ");
    }
    
    size_t turn_ccw(size_t m, size_t n, size_t idx)
    {
            return (n - 1 - idx % n) * m + (idx / n);
    }
    
    size_t turn_cw(size_t m, size_t n, size_t idx)
    {
            return (idx % n) * m + m - 1 - (idx / n);
    }
    
    #define M 5
    #define N 7
    
    int main()
    {
            size_t i, j;
            T a[M][N];
    
            for (i = 0; i < M; ++i)
                    for (j = 0; j < N; ++j)
                            a[i][j] = i * N + j;
    
            rotate(&a[0][0], M, N, turn_ccw);
            dump(N, M, (T (*)[M])&a[0][0]);
            printf("\n");
            rotate(&a[0][0], N, M, turn_cw);
            dump(M, N, (T (*)[N])&a[0][0]);
    }


    turn преобразует линейный индекс элемента из оригинального массива в индекс элемента в повёрнутом массиве.
    Цикл по i переставляет цепочки элементов отображающихся друг в друга с началом в элементе i. Первый цикл по j проверяет, не был ли элемент i уже переставлен в составе более ранней цепочки. Второй цикл по j переставляет одну цепочку.
    Ответ написан
    Комментировать
  • Есть ли способ создать группу процессов не используя setpgid, getpgid, setpgrp, getpgrp?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Целый день ломал голову есть ли альтернатива, но так и не нашел.

    Зачем? Чем плох стандартный интерфейс?
    Ответ написан
  • Как в памяти располагаются аргументы функции с переменным количеством параметров?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Пишу ОС (важно, не выйдет использовать stdarg)

    Остановись на этом месте и почитай про __builtin_va_list, __builtin_va_start, __builtin_va_arg и __builtin_va_end.
    Поскольку компилятор знает ABI функций с переменным числом аргументов, он так же знает, как с ними обращаться.

    А если вызывать такую функцию (с аргументами "test", 'q'):

    void test(char* format, ...)
    {
        char* ptr = format;
    
        for (int i = -10; i < 10; i++)
        {
            putc(*(ptr+i));
        }
    }


    Ожидания были таковы, что хотя бы где-то должна была появиться буква q, чего не произошло.


    Ты просто искал не в том месте: вместо того чтобы двигаться по стеку ты двигался по памяти вокруг первого параметра.
    Вот так нашёл бы...:
    void test(char* format, ...)
    {
        char *ptr = (char *)&format;
    
        for (int i = -10; i < 10; i++)
        {
            putc(*(ptr+i));
        }
    }

    ...если бы аргументы действительно всегда были на стеке. Но это не всегда так -- всё зависит от используемого ABI.
    Ответ написан
    Комментировать
  • Как работает while ( !feof ( cfPtr ) )?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как работает while ( !feof ( cfPtr ) )?

    Как видишь, плохо работает. Потому что man feof говорит нам, что функция возвращает статус потока, а статус потока меняется только от вызова других функций.
    Поэтому по всем правилам было бы написать так:
    FILE * cfPtr = fopen( "test.txt", "rb" );
    char temp;
    
    for (;;) {
      int read = fread( &temp, sizeof( char ), 1, cfPtr );
      if (read == 1) {
        printf("%c\n", temp);
      } else {
        if (feof(cfPtr)) {
          /*случился конец файла*/
        } else if (ferror(cfPtr)) {
          /* случилась ошибка */
        }
        break;
      }
    }
    Ответ написан
    1 комментарий
  • Поведение указателей в Cи?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Это присваивание адреса первого байта массива {0, 0, 0, 0} указателю float?

    Нет. Так можно было бы инициализировать массив. Но если так инициализировать указатель, то это присваивание самому указателю значения 0.

    что будет в i, после данных действий?

    сегфолт при попытке разыменования указателя.

    Начиная с с99 можно сделать так:
    float* arr = (float []){0, 0, 0, 0};
    и это означает создание в текущем контексте (на стеке, если эта строчка внутри функции, или в глобальных данных, если вне) массива из 4 элементов типа флоат, инициализация их нулями и присваивание указателю arr адреса этого массива.
    В этом случае int i = *((int*)arr); проинтерпретирует память первого элемента массива как целое число и присвоит его значение i. По стандарту ieee754 нулевое значение типа float представляется в памяти как 4 нулевых байта, соответственно в i будет записан 0.
    Ответ написан
    6 комментариев
  • Библиотеки GMP, как сохранять результат вычислений?

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

    Экспортировать в массив/импортировать из массива через mpz_export/mpz_import.
    Ответ написан
  • Как перенаправить поток в несколько файлов?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как реализовать то что можно делать в командной строке:
    ls > file1 > file2

    Эта командная строка вовсе не перенаправляет поток в несколько файлов. Вывод попадает только в один из них. Второй файл создаётся, но остаётся пустым.
    Перенаправить вывод в несколько файлов можно командой tee:
    ls | tee file1 file2

    Единственно что мне приходит в голову...вручную записывать в каждый fd.

    Да.
    Ответ написан
    Комментировать
  • Как получить массив элементов на выходе если возвращаемый тип функции int?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    должна возвращать 0

    что написать в return для этого?

    return 0;

    Как получить массив элементов на выходе

    Использовать массив переданный на вход.
    Ответ написан
    Комментировать
  • Функция gets() в C?

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

    Потому что scanf("%d", &n); зачитывает только один int из стандартного ввода. Если ты вводишь число и жмёшь enter, то конец строки остаётся в потоке ввода и читается gets'ом.
    Поэтому нужно либо вводить строку предназначенную для gets следом за числом предназначенным для scanf, либо scanf сделать таким: scanf("%d ", &n);
    Ответ написан
    Комментировать
  • Как передать двумерный статический массив в функцию на Си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Есть массив char mass[1024][1024] и функция int fun(char*)

    в такую функцию можно передать fun(&mass[0][0]).

    Есть ли возможность для указания статического массива как аргумента?

    В смысле массива статической размерности? Легко: int fun(char a[][1000]); ... fun(mass);
    Ответ написан
  • Как запустить приложение через forkpty?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    может быть так?

    #include <pty.h>
    #include <unistd.h>
    #include <thread>
    #include <future>
    #include <iostream>
    #include <string>
    
    ssize_t sz = 1;
    
    int main()
    {
      int mfd;
    
      pid_t pid_fork = forkpty(&mfd, NULL, NULL, NULL);
    
      if (!pid_fork) {
        // Дочерний процесс
        execl("/bin/sh", "-", NULL);
      } else {
        // Родительский процесс
        char buf[1024];
    
        // Async
        auto future = std::async(std::launch::async, [mfd]() {
          std::string line;
          while (sz) {
            std::getline(std::cin, line);
            line = line  + "\n";
            write(mfd, line.c_str(), line.size()); // Нужно направить в дочерний процесс как stdin
            std::this_thread::sleep_for(std::chrono::milliseconds(100));
          }
        });
    
        while (sz = read(mfd, buf, sizeof(buf))) {
          write(STDOUT_FILENO, buf, sz); // Вывод из дочернего процесса stdout
          std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }
    
        exit(0);
      }
    }

    Поскольку это теперь терминал, то имеет смысл установить размеры pty такими же, как у терминала вызывающей программы, например так:

    ...
    #include <sys/ioctl.h>
    ...
      struct winsize ws, *pws = NULL;
    
      if (ioctl(1, TIOCGWINSZ, &ws) >= 0)
        pws = &ws;
      pid_t pid_fork = forkpty(&mfd, NULL, NULL, pws);


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

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    char * suit [4] = { "Hearts", "Diamonds", "Clubs", "Spades" };

    Как изменить строку, инициализированную при объявлении массива символьных указателей, с помощью scanf?

    В данном случае -- только выделив память для новой строки, сделав scanf туда и присвоив указатель на выделенную память элементу массива suit. Напрямую в первоначальный массив -- никак, потому что указатели указывают на константные строки (а возможность писать char * вместо const char * -- это устаревшее средство обеспечения совместимости с древними версиями стандарта).
    Ответ написан
    3 комментария
  • Си. Как добавить программу в автозагрузку?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как добавить программу на Си в автозагрузку Windows?

    Так же как и на любом другом языке -- прописав её в соответствующий ключ реестра.

    И еще: как искать информацию на ответы по Си, если я пишу в гугле "Си как добавить программу в автозагрузку", но везде появляется только С++? Нереально найти ответ.

    Потому что ты задаёшь неправильный вопрос. Язык -- это способ делать действия, а не сами действия. Добавить программу в автозагрузку можно через реестр. Писать в реестр можно через winapi. Справка по winapi есть тут.
    Ответ написан
    Комментировать