• Как расположить буквы русского алфавита в порядке от 1 и 32 и работать с их порядковыми номерами?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Буквы русского алфавита (кроме 'ё') - идут в алфавитном порядке практически во всех кодировках.

    Т.е. вам надо просто вычесть код буквы 'а' из полученной буквы и вы получите число от 0 до 31. Если вам надо с 1 до 32, то прибавьте 1.

    Осталось понять, какой код у буквы 'а'. Это зависит от кодировки. Можете в вашей программе вывести введенные буквы, преобразовав их к int. Передайте ей буквы 'а' и вы получите число, которое вам можно захардкодить в вашей программе.
    Ответ написан
    Комментировать
  • Как реализовать шифрование шифром гаммирования по модулю 2?

    wataru
    @wataru Куратор тега C++
    Разработчик на С++, экс-олимпиадник.
    Можно воспользоваться побитовыми операциями. Сложение по модулю 2 равносильно xor. Т.е. вам надо про xor-ить текст и гамму. Вычитание, что забавно, это тот же самый xor. Побитовый xor в си - это ^.
    Ответ написан
    3 комментария
  • Алгоритм кривой Безье, как можно преобразовать код?

    @vanyamba-electronics
    Кривая задаётся четырьмя точками, что и происходит в данном алгоритме.
    Ответ написан
    Комментировать
  • Как в моём коде можно реализовать сортировку и поиск по “степени риска”?

    tsarevfs
    @tsarevfs Куратор тега C++
    C++ developer
    1. Функция сортировки из стандартной библиотеки: https://en.cppreference.com/w/cpp/algorithm/sort. Обратите пример с lambda функцией. В вашем случае ее параметры будут указатели на Derivativ, и в теле будет сравнение по соответствующему свойству.
    2. У обычного массива нет begin() и end(). Используйте vector вместо массива или https://en.cppreference.com/w/cpp/iterator/begin
    3. Массив со страховками у вас создается только если выбрана 1. Немного логичнее если он будет жить все время работы программы.
    4. Сортировка меняет массив. Вероятно "2" должна создавать копию массива, сортировать его и печатать.
    5. Используйте std::string для хранения строк. Жить станет немного проще и веселее.
    5. Derivative Это что-то производное от чего-то. А у вас наоборот от него производят. Insurance или BaseInsurance более подходящее имя.
    Ответ написан
    Комментировать
  • Как в моём классе реализовать перевод из шестнадцатеричной системы счисления в восьмеричную?

    Если компилятор позволяет, можно использовать itoa, если нет - sprintf. Не C++, но будет работать.
    std::string hexString = "0xBAADF00D";
    char octString[MAX_BUF];
    itoa(std::stoi(hexString, 0, 16 ), octString, 8);


    Придумался мне тут интересный велосипед. Так как шестнадцатеричная и восьмеричная системы счисления основаны на степени двойки, это сильно облегчает нам жизнь (схема тут). 12 двоичных разрядов могут быть записаны как три шестнадцатеричные цифры, либо как четыре восьмеричные. Таким образом, для преобразования шестнадцатеричной строки в восьмеричную, нужно все тройки шестнадцатеричных символов (с конца, начало дополнить нулями) заменить соответствующими четвёрками восьмеричных:

    #include <cstring>
    #include <iostream>
    
    unsigned getHexDigit(char hexChar)
    {
    	if (hexChar >= '0' && hexChar <= '9')
    	{
    		return hexChar - '0';
    	}
    	if (hexChar >= 'A' && hexChar <= 'F')
    	{
    		return 10 + hexChar - 'A';
    	}	
    	if (hexChar >= 'a' && hexChar <= 'f')
    	{
    		return 10 + hexChar - 'a';
    	}
    	return 0;
    }
    
    void getOctQuartet(const char* hex, char* oct)
    {
    	unsigned number = getHexDigit(hex[0]) << 8 | getHexDigit(hex[1]) << 4 | getHexDigit(hex[2]);
    	oct[0] = '0' + (number >> 9 & 07);
    	oct[1] = '0' + (number >> 6 & 07);
    	oct[2] = '0' + (number >> 3 & 07);
    	oct[3] = '0' + (number & 07);
    }
    
    char* getOctString(const char* hexString)
    {
    	const size_t hexStrLen = strlen(hexString);
    	const size_t prefixLen = hexStrLen % 3;
    	char* octString = new char[(hexStrLen - prefixLen + 3) / 3 * 4 + 1];	
    	char* pOct = octString;
    	if (prefixLen > 0)
    	{
    		char hexPrefix[3] = { '0'
    			, prefixLen == 2 ? hexString[0] : '0'
    			, prefixLen == 2 ? hexString[1] : hexString[0] 
    		};
    		getOctQuartet(hexPrefix, octString);
    		pOct += 4;
    	}
    
    	const char* pHex = hexString + prefixLen;
    	while(pHex < hexString + hexStrLen)
    	{
    		getOctQuartet(pHex, pOct);
    		pHex += 3;
    		pOct += 4;
    	}
    	*pOct = '\0';
    
    	return octString;
    }
    
    int main()
    {
    	char hexString[] = "123456789ABCDEF";
    	char* octString = getOctString(hexString);
    	std::cout << octString << std::endl;
    	delete[] octString;
    	return 0;
    }
    Ответ написан
    8 комментариев
  • Как в моём классе реализовать перевод из шестнадцатеричной системы счисления в восьмеричную?

    vt4a2h
    @vt4a2h Куратор тега C++
    Senior software engineer (C++/Qt/boost)
    Самый простой вариант (и супер не эффективный):
    std::string decString("10");
    	
    std::stringstream buf;
    buf << std::oct << std::stoi(decString) << std::endl;
    	
    std::string octString = buf.str();
    std::cout << octString << std::endl;


    Вообще, чтобы число перевести десятичное число, например в восьмеричную систему, можно написать простой цикл на 4-5 строчек.
    Ответ написан
    Комментировать
  • Реализация класса "Строка", помощь в написании программы, правильно ли я делаю?

    myjcom
    @myjcom Куратор тега C++
    Не...
    порядок инициализации в конструкторе
    protected:
      char* Str;  // first
      int Length; // second


    Тогда или так
    String::String(const char* ptr)
      : Str(new char[strlen(ptr) + 1]), Length(strlen(ptr) + 1)
    {
      strcpy(Str, ptr);
    }
    
    String::String(const String& t)
      : Str(new char[t.Length]), Length(t.Length)
    {
      strcpy(Str, t.Str);
    }

    Или поменять местами члены.
    protected:
      int Length;  // first
      char* Str;   // second

    лучше конечно ориентироваться/подглядеть на/в STL
    https://ru.cppreference.com/w/cpp/string/char_traits
    https://ru.cppreference.com/w/cpp/string/basic_string

    hex_string
    только символы '0', '1', '2', '3', '4', '5','6', '7', '8', '9', 'A, 'B', 'C', 'D', 'E', 'F'.

    //...
    struct hex_str_traits
    {
      static bool is_hex_chars(const char* s)
      {
        auto size{ strlen(s) };
        for (auto idx{ 0 }; idx < size; ++idx)
        {
          if (!in_range(s[idx], '0', '9') && !in_range(s[idx], 'A', 'F'))
            return false;
        }
        return true;
      }
      static bool in_range(const int& value, const int& a, const int& b)
      {
        return a <= value && value <= b;
      }
    };
    //...
    
    class hex_string : public String
    {
    //...
    public:
      hex_string(const char* s);
    //...
    };
    //...
    hex_string::hex_string(const char* s) 
      : String( (hex_str_traits::is_hex_chars(s) ? s : "") )
    {
    }
    //...

    Ответ написан
    Комментировать
  • Реализация класса "Строка", помощь в написании программы, правильно ли я делаю?

    Ваш оператор = очень жестоко обходится с правой частью. Написав a=b; я бы очень удивился, обнаружив в b содержимое a.
    Ответ написан
    Комментировать
  • Как будет выглядеть защита от изменения вектора нулевой длины?

    Remove крайне странное название для "режима редактирования". Edit назовите, что ли :-)
    Думаю, проблема в этом: в Remove вы сначала читаете номер n строки для редактирования, но все данные продолжаете вбивать в SP[SP.size() - 1]
    У вектора есть полезные фишки: ссылка на последний элемент: SP.back(), проверка на пустоту: SP.empty()
    Код будет гораздо проще читать, если на элемент, с которым предполагается работа получить ссылку, и все действия делать уже с ней. Т.е. вместо SP[SP.size() - 1] ввести ссылку Sport& curSport = SP[SP.size() - 1]; и дальше работать с ней.
    Помимо проверки вводимых данных неплохо бы ещё сделать проверку выхода за границы массива. Вот тут, например:
    cout << "Введите номер строки, которую Вы хотите отредактировать: ";
      cin >> n;
      cout << "Введите фамилию участника: ";
      cin >> SP[n - 1].Name;
    Ответ написан
    Комментировать
  • Не получается реализовать в классе записи и чтения в/из файла. Какие действия посоветуете?

    myjcom
    @myjcom Куратор тега C++
    Тыц
    #include <iostream>
    #include <string>
    #include <vector>
    #include <fstream>
    
    using std::ofstream;
    using std::vector;
    using std::string;
    using std::cout;
    using std::cin;
    using std::endl;
    
    class Sport
    {
      vector<Sport> Sp;
      char     team;
      double   bal;
      unsigned mesto;
      string   name;
    public:
      Sport(string   _name  = {}, char _team = {}, double _bal = {},
            unsigned _mesto = {}, vector<Sport> sp = {})
          : name {_name}, team{_team}, bal{_bal},
            mesto{_mesto},  Sp{sp} {}
    
    private:
      friend ofstream& operator<<(ofstream& ofs, Sport& sp);
    };
    
    ofstream& operator<<(ofstream& ofs, Sport& sp)
    {
      ofs << sp.name  << ' ';
      ofs << sp.team  << ' ';
      ofs << sp.mesto << ' ';
      ofs << sp.bal   << ' ';
      ofs << endl;
      for(auto& p : sp.Sp)
      {
        ofs << p;
      }
      return ofs;
    }
    
    void writeSportsTo(const char* filename, Sport& sp)
    {
      ofstream of(filename);
      if(of)
      {
        of << sp;
        of.close();
      }
    }
    
    int main()
    {
        constexpr char* filename = "C:\\sports.txt";
        Sport sp;
        writeSportsTo(filename, sp);
        return 0;
    }


    Чтение аналогично.
    Ответ написан
    Комментировать
  • Не получается реализовать в классе записи и чтения в/из файла. Какие действия посоветуете?

    @Free_ze
    Пишу комментарии в комментарии, а не в ответы
    Так, как вы написали в комментариях - не прокатит для сложных объектов, вроде Sport.

    Во-первых, вы записываете и читаете txt-файл в двоичном формате. Вы представляете вообще, как должен выглядеть файл, содержащий данные вашего типа?

    Во-вторых, у вас внутри объекта есть динамические члены (способные изменять свои размеры) - vector и string. Благодаря этому объект имеет многомерное представление в памяти и вам необходимо придумать, как спроецировать его на "плоскую" память, записать его почленно. Если с char, int, float все очевидно (их размеры известены на этапе компиляции: sizeof(char), sizeof(int), sizeof(float)), то для string, например, нужно сначала сохранить его размер (чтобы потом знать, сколько читать из файла), а потом записать содержимое. С vector - аналогично, за тем исключением, что это тот же Sport и вам нужно вызвать функцию сохранения для каждого ребенка текущего объекта (и для их детей, т.е. рекуррентно обойти дерево владения).

    Чтение производить в обратном порядке.
    Ответ написан
    Комментировать