Задать вопрос
Ответы пользователя по тегу C
  • Ошибка при чтении бинарного файла?

    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 есть тут.
    Ответ написан
    Комментировать
  • Почему считывается не по порядку?

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

    Потому что если внимательно прочитать man dup, особенно вот эту часть:
    After a successful return from one of these system calls, the old
    and new file descriptors may be used interchangeably. They refer
    to the same open file description (see open(2)) and thus share file
    offset and file status flags; for example, if the file offset is modified
    by using lseek(2) on one of the descriptors, the offset is also
    changed for the other.

    то окажется, что это поведение предписанное стандартом.
    fhandle2 открыт независимо от fhandle1, поэтому у него все параметры состояния свои.
    Ответ написан
    Комментировать
  • Передача массива в функцию?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    printMAS (&MAS);//будет ошибкой! Почему?

    Будет ошибкой только с точки зрения соответствия типов, потому что тип выражения &MAS -- int (*)[5]. Значение же адреса будет одним и тем же.

    Вот такие инструкции же работают...

    Потому что значение адреса передаётся в них через ... и интерпретируется внутри как void *, т.е. тип исходного адреса больше не имеет значения.
    Ответ написан
    4 комментария
  • Нужно ли вообще очищать память в этом месте?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Нужно ли вообще очищать память в старом указателе?

    Зависит от логики этой функции: если string всегда выделена в куче и нигде не остаётся ссылок на неё, то можно её освобождать. В противном случае -- нет.

    В функции, кстати, нигде не проверяется, что index меньше длины исходной строки, а если случайно передать слишком большой index, функция поломает кучу, записывая за пределы выделенного буфера.
    Ответ написан
    9 комментариев