Advertisement
Sanlover

Untitled

Feb 28th, 2022
1,442
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.41 KB | None | 0 0
  1. /*
  2. Написать класс для эффективной работы со строками, что позволяет форматировать и сравнивать строки, хранить в строках числовые значения и извлекать их. Для этого необходимо реализовать:
  3. • перегруженные операции присвоения и конкатенации;
  4. • операции сравнения и приведения типов;
  5. • преобразование в число любого типа;
  6. • форматный вывод строки.
  7. Написать программу, демонстрирующую работу с этим классом. программа
  8. должна содержать меню, позволяющее осуществить проверку всех методов класса.
  9. */
  10. #define _CRT_SECURE_NO_WARNINGS
  11. #include<iostream>
  12.  
  13. class StringNumber
  14. {
  15.     const int String_Max_Size = 64; //Максимальная длина дробного/целого числа в символах; см. init_def
  16.     char* Str; //Сама строка
  17.     void init_def()
  18.     {
  19.         Str = new char[String_Max_Size]; //Инициализация строки (для ввода целого/дробного числа)
  20.     }
  21.  
  22. public:
  23.     StringNumber(int x, int radix = 10)
  24.     {
  25.         init_def();
  26.         _itoa(x, Str, radix);
  27.     } //Инициализация целым числом
  28.     StringNumber(double x)
  29.     {
  30.         init_def();
  31.         sprintf(Str, "%f", x);
  32.     } //Инициализация дробным числом
  33.     StringNumber(char* x, bool copy = true) //Инициализация строкой; исходная строка остаётся неизменной, если copy=true
  34.     {
  35.         //При copy=false исходная строка может быть удалена, так что лучше его не трогать.
  36.         if (copy)
  37.         {
  38.             Str = new char[strlen(x)];
  39.             strcpy(Str, x);
  40.         }
  41.         else
  42.         {
  43.             Str = x;
  44.         }
  45.     }
  46.  
  47.     StringNumber() //Стандартный конструктор
  48.     {
  49.         Str = const_cast<char*>("");
  50.     }
  51.  
  52.     StringNumber(const StringNumber* base)
  53.     //Конструктор-копия: создаёт этот экземпляр как копию другого; его применение позволяет скопировать строку, вместо того, чтобы пользоваться одной и той же
  54.     {
  55.         StringNumber(base->Str);
  56.     }
  57.  
  58.     char* getString() { return Str; } //Интерфейсный метод, возвращает строку
  59.     bool operator >(StringNumber A) //Сравнение строк - оператор > (strcmp > 0)
  60.     {
  61.         return strcmp(Str, A.Str) > 0;
  62.     }
  63.  
  64.     bool operator <(StringNumber A) //Сравнение строк - оператор < (strcmp < 0)
  65.     {
  66.         return strcmp(Str, A.Str) < 0;
  67.     }
  68.  
  69.     bool operator ==(StringNumber A) //Сравнение строк - оператор == (strcmp == 0)
  70.     {
  71.         return strcmp(Str, A.Str) == 0;
  72.     }
  73.  
  74.     //Обратные функции, являются встроенными (inline); т.е. на этапе компиляции все вызовы этого оператора будут заменены
  75.     //на тело функции (A >= B  -->  !(A < B), и так далее)
  76.     bool operator >=(StringNumber A)
  77.     {
  78.         return !(*this < A);
  79.     }
  80.  
  81.     bool operator <=(StringNumber A)
  82.     {
  83.         return !(*this > A);
  84.     }
  85.  
  86.     bool operator !=(StringNumber A)
  87.     {
  88.         return !((*this) == A);
  89.     }
  90.  
  91.     StringNumber* operator+(StringNumber A)
  92.     {
  93.         //Оператор конкатенации. Исходные переменные остаются неизменными.
  94.         auto temp = new char[strlen(Str) + strlen(A.Str) + 1];
  95.         //Создание буфера размером с две строки (+1 - т.к. 1 нулевой символ, который не считается в strlen)
  96.         strcpy(temp, Str); //Копирование строки в буфер
  97.         char* temp2 = temp + strlen(temp); //Указатель на то место в буфере, куда будет скоп вторая строка
  98.         strcpy(temp2, A.Str); //Копирование второй строки в буфер
  99.         return new StringNumber(temp); //И возврат новой строки
  100.     }
  101.  
  102.     StringNumber* operator=(StringNumber E)
  103.     {
  104.         if (E.Str == Str)return this; //Для присваиваний типа A = A;
  105.         delete[] Str;
  106.         //Освобождение строки (delete[] Str; для 'Str = new char[...]', а delete Str;'Str(char*)malloc(...);'
  107.         Str = new char[strlen(E.Str)]; //Этот и следующий - создание и копирование строки
  108.         strcpy(Str, E.Str);
  109.         return this;
  110.     }
  111.  
  112.     operator int() const //Приведение к целому
  113.     {
  114.         return atoi(Str);
  115.     }
  116.  
  117.     operator float() const //Приведение к дробному
  118.     {
  119.         return static_cast<float>(atof(Str));
  120.     }
  121.  
  122.     int print(char* format) //Форматированный вывод; использование: A->print("My string is %s!");
  123.     {
  124.         return printf(format, Str);
  125.     }
  126.  
  127.     int printdbl(char* format) { return printf(format, static_cast<float>(*this)); }
  128.     //Форматированный вывод дробного (printdbl("%f");)
  129.     int printint(char* format) { return printf(format, static_cast<int>(*this)); }
  130.     //Форматированный вывод целого (printdbl("%i");)
  131. };
  132.  
  133. int main()
  134. {
  135.     auto A = new StringNumber(), B = new StringNumber(); //Два экземпляра нашего класса со стандартными конструкторами
  136.     int a = 0; //Это - выбранный пункт 'меню'.
  137.     while (a != 10)
  138.     {
  139.         if (a == 0)
  140.             printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
  141.                    "Menu: select one.",
  142.                    "0) Display this menu again;",
  143.                    "1) Type new int to put into A;",
  144.                    "2) Type new double to put into A;",
  145.                    "3) Type new string to put into A;",
  146.                    "4) Copy A into B;",
  147.                    "5) Concat A and B;",
  148.                    "6) Compare A and B;",
  149.                    "7) Display A and B;",
  150.                    "8) Display A and B, as int (radix 10).",
  151.                    "9) Display A and B, as float.",
  152.                    "10) Exit.");
  153.         std::cout << "> ";
  154.         std::cin >> a;
  155.         switch (a)
  156.         {
  157.         case 1:
  158.             printf("%s", "Format: int radix (like, '5 10'): "); //Ввод целого числа в A; пример: 5 10
  159.             int b;
  160.             std::cin >> b >> a; //a - для хранения radix, чтобы не объявлять новой переменной.
  161.             A = new StringNumber(b, a);
  162.             a = 1;
  163.             break;
  164.         case 2:
  165.             printf("%s", "Format: float: "); //Ввод дробного числа в A; пример: 5.10
  166.             float x;
  167.             std::cin >> x;
  168.             A = new StringNumber(x);
  169.             break;
  170.         case 3:
  171.             printf("%s", "Enter string: "); //Ввод строки в A
  172.             char Q[128];
  173.             getchar(); //"Съедание" лишнего перевода строки
  174.             gets_s(Q); //Получение новой строки
  175.             A = new StringNumber(Q);
  176.             break;
  177.         case 4:
  178.             std::cout << "Succesful copy.\n";
  179.             B = A; //Копирование A в B. A - не меняется, что является результатом оператора =
  180.             a = 1; //std::cin.get(); //Какая-то магия, но без неё всё уходит в бесконечный цикл.
  181.             break;
  182.         case 5:
  183.             std::cout << "Result: " << (*A + *B)->getString() << '\n'; //Конкатенация А и В
  184.             break;
  185.         case 6:
  186.             printf("%s\n", (*A > *B) ? "A>B" : (*A < *B) ? "A<B" : "A==B"); //Сравнение А и В
  187.             break;
  188.         case 7:
  189.             A->print(const_cast<char*>("A: %s\n"));
  190.             B->print(const_cast<char*>("B: %s\n")); //Вывод А и В как строк, используя встроенную функцию
  191.             break;
  192.         case 8:
  193.             A->printint(const_cast<char*>("A: %i\n"));
  194.             B->printint(const_cast<char*>("B: %i\n")); //Вывод А и В как чисел, тоже через встр-ю ф-ю
  195.             break;
  196.         case 9:
  197.             A->printdbl(const_cast<char*>("A: %f\n"));
  198.             B->printdbl(const_cast<char*>("B: %f\n"));
  199.             break; //Что-то это мне напоминает...
  200.         case 10: break; // Чтобы при a=10 не соскочить на default:
  201.         default: //Если a не принадлежит 1-10, то присваиваем 0, чтобы показать меню в начале цикла
  202.             a = 0;
  203.             break;
  204.         }
  205.     }
  206.     return 0;
  207. }
  208.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement