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

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Возможно проблема в используемой кодировке для самого файла - вывод-то в консоль:
    - Консоль распознает UTF-8/Unicode
    - Файл открыт в windows-1251

    Тут надо просто поиграться с кодировкой файла в VS. Начни с UTF-8/Unicode, а дальше тыкай, пока не заведется
    Ответ написан
  • Почему GCC не видит встроенную атомарную операцию?

    AshBlade
    @AshBlade Автор вопроса
    Просто хочу быть счастливым
    Разобрался.
    Есть 2 замечания:
    1. Поближе посмотрел на сигнатуру

    bool __atomic_compare_exchange (type *ptr, type *expected, type *desired, bool weak, int success_memorder, int failure_memorder)


    Короче говоря, мне нужно было передавать не указатели, а указатели на указатели. Исправил:

    if (__atomic_compare_exchange(&l.head->next,  (struct entry**)NULL, &new_next, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))


    Но потом начал ловить SEGFAULT. И тут пришел к 2 замечанию

    2. Не заметил следующего в документации:

    This built-in function implements an atomic compare and exchange operation. This compares the contents of *ptr with the contents of *expected. If equal, the operation is a read-modify-write operation that writes desired into *ptr. If they are not equal, the operation is a read and the current contents of *ptr are written into *expected. weak is true for weak compare_exchange, which may fail spuriously, and false for the strong variation, which never fails spuriously. Many targets only offer the strong variation and ignore the parameter. When in doubt, use the strong variation.


    Т.е. если значение во 2 аргументе не равно значению из 1, то (!!!) по месту указателя 2 записывается полученное из указателя 1 значение. А у меня там был NULL (конец списка обозначается NULL). Заменил на корректно выделенный элемент списка и все заработало

    int main(int argc, char const *argv[])
    {
        struct list l;
    
        l.head = (struct entry *)malloc(sizeof(struct entry));
        l.head->next = NULL;
        l.head->value = 123;
        struct entry *old_next = (struct entry *)malloc(sizeof(struct entry));
        old_next->next = NULL;
        old_next->value = 555;
        l.head->next = old_next;
    
        struct entry *new_next = (struct entry *)malloc(sizeof(struct entry));
        new_next->value = 444;
        new_next->next = NULL;
        if (__atomic_compare_exchange(&l.head->next, &old_next, &new_next, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
        {
            printf("ok\n");
            printf("success: next = %d\n", l.head->next->value);
        }
        else
        {
            printf("failed\n");
        }
    
        return 0;
    }


    Не хочу возиться со всякими dummy узлами, поэтому буду использовать __sync_bool_compare_and_swap. Вот такой код сработает:
    int main(int argc, char const *argv[])
    {
        struct list l;
    
        l.head = (struct entry *)malloc(sizeof(struct entry));
        l.head->next = NULL;
        l.head->value = 123;
    
        struct entry *new_next = (struct entry *)malloc(sizeof(struct entry));
        new_next->value = 444;
        new_next->next = NULL;
    
        if (__sync_bool_compare_and_swap(&l.head->next, (struct entry *)NULL, new_next))
        {
            printf("ok\n");
            printf("success: next = %d\n", l.head->next->value);
        }
        else
        {
            printf("failed\n");
        }
    
        return 0;
    }


    UPD: спасибо res2001, разобрался лучше. итоговый вариант

    #include <stdatomic.h>
    
    int main(int argc, char const *argv[])
    {
        struct list l;
    
        l.head = (struct entry *)malloc(sizeof(struct entry));
        l.head->next = NULL;
        l.head->value = 123;
    
        struct entry *new_next = (struct entry *)malloc(sizeof(struct entry));
        new_next->value = 444;
        new_next->next = NULL;
        struct entry *tmp = NULL;
        if (atomic_compare_exchange_strong(&l.head->next, &tmp, new_next))
        {
            printf("ok\n");
            printf("success: next = %d\n", l.head->next->value);
        }
        else
        {
            printf("failed\n");
        }
    
        return 0;
    }


    Просто надо создать переменную указатель, которой присвоить NULL. Также использовал atomic_compare_exchange_strong из stdatomic вместо расширения GCC - он под капотом использует __atomic_* вместо устаревшего __sync_*
    Ответ написан
    1 комментарий
  • Как транслировать аудио в микрофон, py, c#, c++?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Не совсем понял, что ты хочешь. Возможно, создать виртуальный микрофон и дальше использовать именно его - https://codeease.net/programming/python/virtual-mi...
    Ответ написан
    1 комментарий
  • Как переобразовать string в const unsigned char* в C++?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    // str - строка типа std::string
    const unsigned char* str_ptr = (const unsigned char*) str.c_str();
    Ответ написан
    2 комментария
  • Как исправить ошибку sqlite3?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Ты создаешь таблицу со столбцами login и password, но потом зачем-то создаешь подготовленный select со столбцами q, w и name: во-первых их нет в таблице (ты их не создавал), во-вторых ты не проверяешь результат выполнения sqlite3_prepare_v2.
    Вот и получается, что во 2 sqlite3_exec (insert) ты получаешь ошибку не insert запроса, а prepare

    - Либо исправляй этот запрос + добавляй проверки на prepare
    - Либо удали этот prepare, т.к. нигде не используешь (в этом коде)
    Ответ написан
  • Возможно ли сделать nested enum c/c++?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Если мы говорим про C, то так делать нельзя:
    1. Вложенные в enum определения делать нельзя - это ограничение самого синтаксиса (дока)
    2. Для использования перечислений не надо указывать само название перечисления. Т.е. не OBJ::SOMETHING, а просто SOMETHING. Т.е. видимость глобальная и нельзя дублировать названия, даже для разных enum

    В случае C++ аналогично. Есть хак - использование неймспейсов или структур для топ левела, но не в твоем случае - ты хочешь топ левел перечислениям значения задавать

    На мой взгляд тут решение:
    1. Разбить их на различные перечисления
    2. Добавить каждому префикс
    enum OBJ = 0 {
           Default = 0,
           Something_Something1 = 1,
           Something_Something1 = 2,
           Something = 7
    };
    Ответ написан
    Комментировать
  • Как вписывать инпут во время дебагга c++ (g++)?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Пиши во вкладке Terminal (она рядом)
    Ответ написан
  • Фреймворки для кросс-платформенной разработки. Практикуют ли переписывание под разные платформы?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Windows Forms - это только Windows, т.к. он построен вокруг нативных системных вызовов Windows. Вообще-то я однажды писал Windows Forms для Linux, но там очень много было костылей и багов, поэтому - нет, не надо.

    Что касается кросс-платформенной разработки на C#.
    Если речь идет про разработку оконных приложений, то тут 2 варианта:
    - Avalonia UI - это кросс-платформенный фреймворк, разрабатываемый сообществом (не майкрософтом), очень похож на WPF. Есть почти все платформы
    - MAUI - это новый кросс-платформенный фреймворк, разрабатываемый майкрософтом. Он довольно новый, поддерживает множество платформ (по странице документации даже Linux (GTK#)). Но он довольно сырой и по отзывам очень много багов
    - WebAssembly/Blazor - фреймворк для создания PWA, веб-приложений, но можно и для мобильных приложений
    Ответ написан
    3 комментария
  • GCC Добавляет лишние пробелы при компиляции?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Скорее всего проблема в кодировке файла. Попробуй сконвертировать формат файла в utf-8, если другой, и дополнительно смени тип новой строки с \r\n на \n (не уверен, что важно)
    Ответ написан
    Комментировать
  • Как исправить ошибку?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    event - это функция, а не поле, поэтому event(func) - невалидная конструкция для списка инициализации (тебе компилятор об этом и говорит)
    Если хочешь, чтобы вызываемая функция инициализировалась в конструкторе, то храни само поле функции и внутри event() ее вызывай. Примерно так:
    class menu_item
    {
    public: 
    	menu_item(std::string name, std::function<void()> func) : _name(name), _func(func)
    	{
    		
    	}
    	
    	void event()
            {
                  _func();
            }
    	
    	std::string const& name = _name;
    	
    private: 
    	std::string _name;
            std::function<void()> _func
    };
    Ответ написан
  • Что можно разработать на C++ кроме нативных GUI-приложений и серверной части веб-приложений?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Изучать новый ЯП стоит для расширения своего кругозора. В твоем случае - надо понять фичи C++, которых нет в C#/TypeScript.
    В данном случае, это:
    - управление памятью (new/delete)
    - RAII
    - move семантика, l-/r- value ссылки
    - Шаблоны, SFINAE
    - Системные вызовы и простая кроссплатформенность (C# предалагает свою абстракцию над ОС и тебе об этом думать не нужно)

    Поэтому и проект надо выбирать соответствующий (управление памятью, взаимодействие с ОС напрямую и т.д.).
    В качестве такого, могу предложить варианты:
    - Консольная утилита для изменения метаданных изображения (это больше про управление памятью, т.к. целое изображение в памяти надо эффективно хранить)
    - Библиотека для HTTP запросов (это больше про ОС и кросплатформенность)
    - Собственная база данных, можешь хранить все в JSON - главное это работа с диском и фс

    Дополнительно - build-your-own-x
    Ответ написан
    Комментировать
  • Как использовать русские символы из файла в качестве ключа для unordered_map?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Попробуй указать локаль - setlocale(LC_ALL, "Russian");
    Ответ написан
    9 комментариев
  • Как создать многомерный массив в одной области памяти?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Одномерный массив размером X * Y - единственное решение, если нужен непрерывный участок памяти.
    Для получения первого индекса - index / X, для второго - index % X.
    Но надо позаботиться - чтобы места было достаточно, иначе однажды получишь OOM либо когда место закончится, либо при сильной фрагментации памяти.

    Вариант с "зубчатым" массивом, тоже норм - отложенное выделение можно реализовать. Но по скорости будет проигрывать из-за локальности данных. Хотя, если нужен непрерывный участок - уже не подходит
    Ответ написан
    2 комментария
  • Как получить постоянную ячейку памяти?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Память выделяется в рантайме динамически, существует ASLR, расположение зависит от имеющихся в памяти объектов/библиотек, уже выделенных объектов, GC и т.д.. Короче говоря, после перезагрузки ты всегда получишь другие адреса.

    Единственное решение - найти алгоритм, который позволит находить нужный адрес памяти. По другому никак.
    Ответ написан
    5 комментариев
  • Можно ли в c++ помечать код метками?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Если это нативный C++ - нет. В нем нет такого синтаксиса.
    Если это CLI/C++ (яп для .net), то да
    Ответ написан
    7 комментариев
  • Как начать программировать с использованием DirectX?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    На прямом DirectX отрисовывать - сложно, а учитывая, что опыта нет - самоубийство.
    Рекомендую начать с SDL. Это достаточно простой (проще, чем DirectX) фреймворк для графики. Он может использовать DirectX в качестве бэка.
    Вот тут нашел пример для этой связки
    Ответ написан
    2 комментария
  • Как исправить ошибку vector subscript out of range?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Скорее всего ты выходишь за пределы массива.
    Ответ написан
    Комментировать
  • Как быстро освоить c#, если я работаю на c++?

    AshBlade
    @AshBlade Куратор тега C#
    Просто хочу быть счастливым
    Пролистываешь метанит параллельно повторяешь примеры.
    Это за 1-2 дня можно сделать.
    Синтаксис довольно простой и немного похож на C++, поэтому изучится легко. Дальше уже идешь в проект и изучаешь какие библиотеки/фичи платформы там используются - их много поэтому лучше не распыляться на них во время обучения
    Ответ написан
    Комментировать
  • Как ограничить кол-во символов после точки при вводе данных в С++?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Если нужно округление до определенного кол-ва знаков после запятой, то вот это может помочь:
    unsigned int powers[] = {1, 10, 100, 1000, 10000, 100000};
    
    double round_precision(double number, unsigned int precision) {
      unsigned int coef = powers[precision];
      long temp = number < 0 ? -number * coef : number * coef;
      return (double)temp / coef;
    }


    Также есть вариант записывать число в std::stringstream с нужной точностью, а потом десериализовывать, но т.к. это затратно для этого случая не описал.
    Ответ написан
    Комментировать
  • Как сделать преобразование переменной в С++?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Если вопрос в том - как возвращать ошибку в качестве ответа, то есть решения:
    - Создать специальный класс Result, который будет содержать либо ответ, либо строку ошибки
    - Возвращать double.NaN - маркер ошибки
    - Кидать исключение

    UPD: если функция возвращает double, а ты хочешь передать std::string, то ничего не получится - типизация строгая
    Ответ написан
    1 комментарий