• Как выводить русские символы в си?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как это работает

    Поскольку русский -- не часть ASCII, работает это по-разному в зависимости от кодировки. Если предположить, что исходник в UTF-8, то русские символы закодированы двумя байтами, а %c выводит только один. Если на одном выведенном байте остановиться -- получится фигня с вопросом. Но если вывести подряд все байты многобайтового символа -- получится этот символ.

    как исправить

    вариантов несколько. Самый простой -- выводить строки целиком. Если надо выводить посимвольно, можно узнавать количество байт в представлении одного символа функцией mblen, типа того:
    #include <locale.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main() {
      char *a = "Привет, мир";
      int s;
      setlocale(LC_ALL, "");
      for (; *a != '\0'; a+=s) {
        s = mblen(a, strlen(a));
        printf("%.*s-", s, a);
        }
        return 0;
    }

    Здесь setlocale нужен для того, чтобы mblen понял, в какой кодировке символы на входе. Локаль в момент выполнения должна быть совместимой с кодировкой исходника в момент компиляции, если это условие не выполняется, работать будет неправильно.

    Ещё вариант -- работать не с многобайтовой кодировкой а с wchar_t:
    #include <locale.h>
    #include <stdio.h>
    #include <stddef.h>
    
    int main() {
      wchar_t *a = L"Привет, мир";
      setlocale(LC_ALL, "");
      for (; *a != '\0'; a++) {
        printf("%lc-", *a);
        }
        return 0;
    }

    Здесь setlocale нужен для другого: он говорит внутренностям printf в какую локаль выполняется вывод чтобы в неё конвертировать wchar_t. Если локаль во время выполнения не будет соответствовать кодировке исходника, код всё равно будет работать.
    Ответ написан
    2 комментария
  • Bsd-socket. Почему бесконечное чтение при http запросе?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    При повторной итерации read, по идее, должен вернуть 0, так как все прочитано

    Неа, не так это работает. 0 из read возвращается в одном единственном случае: если та сторона закрыла сокет на передачу и все посланные ею данные получены. В противном случае (сокет не закрыт) поведение зависит от настроек сокета: синхронный сокет при попытке чтения может заблокироваться в функции read или вернуть из неё -1 (и установить errno, например, в EINTR). Асинхронный сокет вернёт из read -1 и установит errno в EAGAIN или EWOULDBLOCK.
    Ваш HTTP-сервер наверняка оставляет соединение открытым после того как прислал ответ на первый запрос, это можно понять по наличию заголовка Connection: Keep-Alive или отсутствию заголовка Connection: close в его ответе если это HTTP/1.1. Его можно попросить закрыть соединение после ответа, послав запрос с заголовком Connection: close или можно избежать блокировки в read прочитав только данные ответа размер которых прислан в заголовке ответа Content-Length.
    Ответ написан
    2 комментария
  • Почему возникла ошибка при сортировке?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В чём ошибка?

    В том, что функция qSort при попытке сортировки массива одинаковых значений все их сносит в массив right, оставляя массив left пустым. Циклический алгоритм на этом месте зациклился бы, а рекурсивный с не-хвостовой рекурсией выходит за ограничение размера стека.
    Ответ написан
    Комментировать
  • FASM Что не так с процедурой?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Что не так с процедурой?

    stdcall test_proc, 11
    …
    proc test_proc, ms
    …
    mov rbx, qword ptr ms


    ABI вызова не совпадает с ABI процедуры: 64-битный stdcall передаёт первый параметр в rcx, а test_proc ожидает его на стеке, в чём легко убедиться пропустив результат через objdump:

    403004:       48 c7 c1 0b 00 00 00    mov    $0xb,%rcx
    40300b:       e8 19 00 00 00          callq  0x403029
    …
    40307b:       48 8b 5d 10             mov    0x10(%rbp),%rbx
    Ответ написан
    Комментировать
  • Как правильно в bash скрипте использовать $?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    дамп postgres, после чего, если комманда с дампом выполнилась…
    pg_dump -U postgres zkgu | gzip > /mnt/NStore/1c-sqldump/$n$d.gz
    EXIT_STATUS=$?
    if [[$EXIT_STATUS -eq "0"]]

    Вместо двух лишних действий с текстовым представлением то же самое можно сделать идиоматично:
    if pg_dump -U postgres zkgu | gzip > /mnt/NStore/1c-sqldump/$n$d.gz


    Но есть одно "но": написанная вами команда делает не то, что вы хотели: $? -- это статус завершения последней команды, а у вас там пайплайн и последняя команда -- gzip. Статус завершения именно pg_dump не проверяется, ни первым вариантом, ни вторым.
    Ответ написан
    Комментировать
  • Почему substr работает странно?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Последняя кавычка ни в какую не хочет убираться, не могу понять, в чем дело
    std::string variable_value = var.substr(variable_value_start + 1, variable_value_end - 1);

    Второй параметр std::string::substr -- это длина выделяемой подстроки, а не индекс конца.
    Должно быть
    std::string variable_value = var.substr(variable_value_start + 1,
                                            variable_value_end - variable_value_start - 1);
    Ответ написан
  • Что не так с кодом на C++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    for (int i = 0; i<2; i++){
        group.PutCar(i,Car(marks[i],powers[i],costs[i],displaces[i]));
      }

    -- заполняет элементы группы 0 и 1
    group[2].Print();

    -- пытается напечатать элемент группы 2, не заполненный. Думаю, что дело в этом.

    Ещё пара глюков:
    void Group::Print(){
      for (int i = 0; i<sizeof(array); i++){
        array[i].Print();
      }
    };

    sizeof работает не так и тут делает не то, что вы ожидаете. Для количества элементов в группе используйте имеющийся в классе Group size.

    operator double (){
        int summ = 0;
        for(int i = 0; i < sizeof(array); i++){
        summ += array[i].getCost();
        }

    то же самое здесь.

    Традиционно добавлю, что правильным было бы использование std::string (в Car) и std::vector (в Group), но подозреваю, что это это было такое задание.
    Ответ написан
    Комментировать
  • Как выводить числа на семисегментный дисплей в Microprocesor Simulator 5v32?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    цифра три на левой части дисплея имеет код 9Е и чтобы вывести результат сложения 1 + 2 мне надо 3 как-то преобразовать в 9Е

    Типовое решение этой задачи -- через таблицу преобразования, где индекс -- это то, что нужно отобразить, а содержимое -- это то, что нужно записать в порт для отображения. Для вывода цифр от 0 до 9 и вашего дисплея таблица будет такой:
    0xfa, 0x0a, 0xb6, 0x9e, 0x4e, 0xdc, 0xfc, 0x8a, 0xfe, 0xde
    .
    Ответ написан
    1 комментарий
  • Почему вместо строки появляется мусор?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему вместо строки появляется мусор?
    size_t xpath_formatted_size = vsnprintf(NULL, 0, xpath, arguments);
      char* xpath_formatted = malloc(xpath_formatted_size);
      vsnprintf(xpath_formatted, xpath_formatted_size, xpath, arguments);


    Потому что 1) результат возвращаемый vsnprintf не включает конечный 0, а вот аргумент vsnprintf обозначающий размер буфера должен включать место для конечного 0. И 2) вызов vsnprintf(…, arguments) меняет arguments.

    Как это исправить?

    Как-то так:
    char* xpath_format(const char* xpath, ...)
    {
      va_list arguments;
      va_start(arguments, xpath);
    
      size_t xpath_formatted_size = vsnprintf(NULL, 0, xpath, arguments) + 1;
      va_end(arguments);
      va_start(arguments, xpath);
      char* xpath_formatted = malloc(xpath_formatted_size);
      vsnprintf(xpath_formatted, xpath_formatted_size, xpath, arguments);
    
      va_end(arguments);
      return xpath_formatted;
    }
    Ответ написан
    Комментировать
  • Как разархивировать архив tar.gz, в котором архив и т.д?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Studencheskaya32 --to-command -- это прикольно.
    Но мне больше нравится решение с -O:
    tar -xzvOf archive.tar.gz | tar -xzvO | tar -xzvO | … | tar -xzvO | tar -xzv
    Ответ написан
    Комментировать
  • Можно ли записать структуру в файл используя basic_ofstream?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Можно ли записать структуру в файл используя basic_ofstream?

    Можно, но для этого не нужно делать её тип аргументом шаблона basic_ofstream.
    Ответ написан
  • Что за странная константа?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Зачем он для такой строчки на 69, 70ой строчке добавляет к j такую странную константу.

    В конечном коде выглядит действительно загадочно. Если вызывать компилятор с ключом -fdump-tree-all (фиг знает, как сделать это на godbolt.org, я проверял локально), то уже в самом первом дампе можно увидеть, что if (arr[j - 1] > arr[j]) превращается в это:
    if (*(arr + ((sizetype) j + 1073741823) * 4) > *(arr + (sizetype) ((unsigned int) j * 4)))

    1073741823 -- это 0x3fffffff, 30 единичных бит, т.е. 30-битная -1. Дальше j + 1073741823 превратилось в
    add     r3, r3, #1073741824
    subs    r3, r3, #1

    т.е. в j + 1073741824 - 1. После умножения на 4 старшие два бита j теряются, но в чём смысл использования 30-битной -1 вместо 32-битной -- мне непонятно.
    Поскольку константа появляется ещё до начала архитектурно-зависимых преобразований, она фигурирует в выводе для всех 32-битных архитектур поддерживаемых gcc. Интересно, что это началось между gcc-4.6 и gcc-5, до этого в этом месте генерировался просто sub r3, r3, #1. Ещё интересно, что даже с -O2 эта константа остаётся в сгенерированном коде, а исчезает только с -Os. Выглядит как регрессия.
    Ответ написан
    Комментировать
  • Как правильно инициализировать массив в C?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В этом коде проблема не в том, что массив d не инициализирован, а в том, что колическтво итераций цикла вывода массива d не зависит от того, сколько элементов было занесено в этот массив. Правильным решением было бы как-то их связать, например так:
    int i = 0, n;
    while (piece != NULL)
    {
        d[i] = piece;
        piece = strtok(NULL, " ");
        i++;
    }
    n = i;
    for (i = 0; i < n; i++) {
        if(i%2==0)
            printf("%s ",d[i]);
    }
    Ответ написан
    1 комментарий
  • Почему возникает такая проблема с динамическим массивом (Язык Си)?

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

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

    Я бы не сказал, что она "продолжает работать", но у нас, видимо, разные определения понятия "работать". Никакие новые исполняемые файлы в такой системе не могут быть запущены, потому что никаких файлов нет, а запущенные процессы -- да, могут продолжать выполняться и форкаться, пока им от файловой системы не нужны операции использующие имена файлов.
    Ну и, справедливости ради, надо отметить, что место занятое открытыми на момент выполнения команды rm -rf / файлами не будет освобождено и их содержимое не будет потеряно, пока они не будут закрыты. Можно будет продолжать читать и писать в них, в т.ч. ядро будет продолжать использовать их для реализации механизмов виртуальной памяти.
    Ответ написан
    Комментировать
  • Почему не работает функция fscanf?

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

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

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

    В linux есть драйвер scsi/qla2xxx, можно заглянуть в его список поддерживаемых PCI ID, чтобы понять, подходит ли он для этой платы. Если подходит, то можно почитать, как он взаимодействует с железом.
    Ответ написан
    Комментировать
  • Как переделать initrd (Altlinux 8 SP)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    нужно выкинуть все лишнее из /lib/modules/5.10.144-std-def-alt0.c9f.2

    Это сравнительно легко сделать: нужно оставить только те модули, которые видны в lsmod после успешной загрузки.
    Ответ написан
    Комментировать
  • Почему не удается подключиться к Postgres(VirtualBox) из хостовой машины?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    в pg_hba.conf должно быть что-то типа того:
    host all all 0.0.0.0/0 md5
    host all all ::0/0 md5

    для приёма любых подключений с любого адреса.
    Ответ написан
  • Как подключить роутер 12в 1,5а к автомобильному аккумулятору?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как подключить роутер: напрямую от акума или через какой-то преобразователь, чтобы брал 12в и выдавал 12в, а ток понижал до 1,5а?

    Можно напрямую. Он сам возьмёт нужные ему 1.5А.
    Ответ написан
    8 комментариев