Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Написать класс для эффективной работы со строками, что позволяет форматировать и сравнивать строки, хранить в строках числовые значения и извлекать их. Для этого необходимо реализовать:
- • перегруженные операции присвоения и конкатенации;
- • операции сравнения и приведения типов;
- • преобразование в число любого типа;
- • форматный вывод строки.
- Написать программу, демонстрирующую работу с этим классом. программа
- должна содержать меню, позволяющее осуществить проверку всех методов класса.
- */
- #define _CRT_SECURE_NO_WARNINGS
- #include<iostream>
- class StringNumber
- {
- const int String_Max_Size = 64; //Максимальная длина дробного/целого числа в символах; см. init_def
- char* Str; //Сама строка
- void init_def()
- {
- Str = new char[String_Max_Size]; //Инициализация строки (для ввода целого/дробного числа)
- }
- public:
- StringNumber(int x, int radix = 10)
- {
- init_def();
- _itoa(x, Str, radix);
- } //Инициализация целым числом
- StringNumber(double x)
- {
- init_def();
- sprintf(Str, "%f", x);
- } //Инициализация дробным числом
- StringNumber(char* x, bool copy = true) //Инициализация строкой; исходная строка остаётся неизменной, если copy=true
- {
- //При copy=false исходная строка может быть удалена, так что лучше его не трогать.
- if (copy)
- {
- Str = new char[strlen(x)];
- strcpy(Str, x);
- }
- else
- {
- Str = x;
- }
- }
- StringNumber() //Стандартный конструктор
- {
- Str = const_cast<char*>("");
- }
- StringNumber(const StringNumber* base)
- //Конструктор-копия: создаёт этот экземпляр как копию другого; его применение позволяет скопировать строку, вместо того, чтобы пользоваться одной и той же
- {
- StringNumber(base->Str);
- }
- char* getString() { return Str; } //Интерфейсный метод, возвращает строку
- bool operator >(StringNumber A) //Сравнение строк - оператор > (strcmp > 0)
- {
- return strcmp(Str, A.Str) > 0;
- }
- bool operator <(StringNumber A) //Сравнение строк - оператор < (strcmp < 0)
- {
- return strcmp(Str, A.Str) < 0;
- }
- bool operator ==(StringNumber A) //Сравнение строк - оператор == (strcmp == 0)
- {
- return strcmp(Str, A.Str) == 0;
- }
- //Обратные функции, являются встроенными (inline); т.е. на этапе компиляции все вызовы этого оператора будут заменены
- //на тело функции (A >= B --> !(A < B), и так далее)
- bool operator >=(StringNumber A)
- {
- return !(*this < A);
- }
- bool operator <=(StringNumber A)
- {
- return !(*this > A);
- }
- bool operator !=(StringNumber A)
- {
- return !((*this) == A);
- }
- StringNumber* operator+(StringNumber A)
- {
- //Оператор конкатенации. Исходные переменные остаются неизменными.
- auto temp = new char[strlen(Str) + strlen(A.Str) + 1];
- //Создание буфера размером с две строки (+1 - т.к. 1 нулевой символ, который не считается в strlen)
- strcpy(temp, Str); //Копирование строки в буфер
- char* temp2 = temp + strlen(temp); //Указатель на то место в буфере, куда будет скоп вторая строка
- strcpy(temp2, A.Str); //Копирование второй строки в буфер
- return new StringNumber(temp); //И возврат новой строки
- }
- StringNumber* operator=(StringNumber E)
- {
- if (E.Str == Str)return this; //Для присваиваний типа A = A;
- delete[] Str;
- //Освобождение строки (delete[] Str; для 'Str = new char[...]', а delete Str;'Str(char*)malloc(...);'
- Str = new char[strlen(E.Str)]; //Этот и следующий - создание и копирование строки
- strcpy(Str, E.Str);
- return this;
- }
- operator int() const //Приведение к целому
- {
- return atoi(Str);
- }
- operator float() const //Приведение к дробному
- {
- return static_cast<float>(atof(Str));
- }
- int print(char* format) //Форматированный вывод; использование: A->print("My string is %s!");
- {
- return printf(format, Str);
- }
- int printdbl(char* format) { return printf(format, static_cast<float>(*this)); }
- //Форматированный вывод дробного (printdbl("%f");)
- int printint(char* format) { return printf(format, static_cast<int>(*this)); }
- //Форматированный вывод целого (printdbl("%i");)
- };
- int main()
- {
- auto A = new StringNumber(), B = new StringNumber(); //Два экземпляра нашего класса со стандартными конструкторами
- int a = 0; //Это - выбранный пункт 'меню'.
- while (a != 10)
- {
- if (a == 0)
- printf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
- "Menu: select one.",
- "0) Display this menu again;",
- "1) Type new int to put into A;",
- "2) Type new double to put into A;",
- "3) Type new string to put into A;",
- "4) Copy A into B;",
- "5) Concat A and B;",
- "6) Compare A and B;",
- "7) Display A and B;",
- "8) Display A and B, as int (radix 10).",
- "9) Display A and B, as float.",
- "10) Exit.");
- std::cout << "> ";
- std::cin >> a;
- switch (a)
- {
- case 1:
- printf("%s", "Format: int radix (like, '5 10'): "); //Ввод целого числа в A; пример: 5 10
- int b;
- std::cin >> b >> a; //a - для хранения radix, чтобы не объявлять новой переменной.
- A = new StringNumber(b, a);
- a = 1;
- break;
- case 2:
- printf("%s", "Format: float: "); //Ввод дробного числа в A; пример: 5.10
- float x;
- std::cin >> x;
- A = new StringNumber(x);
- break;
- case 3:
- printf("%s", "Enter string: "); //Ввод строки в A
- char Q[128];
- getchar(); //"Съедание" лишнего перевода строки
- gets_s(Q); //Получение новой строки
- A = new StringNumber(Q);
- break;
- case 4:
- std::cout << "Succesful copy.\n";
- B = A; //Копирование A в B. A - не меняется, что является результатом оператора =
- a = 1; //std::cin.get(); //Какая-то магия, но без неё всё уходит в бесконечный цикл.
- break;
- case 5:
- std::cout << "Result: " << (*A + *B)->getString() << '\n'; //Конкатенация А и В
- break;
- case 6:
- printf("%s\n", (*A > *B) ? "A>B" : (*A < *B) ? "A<B" : "A==B"); //Сравнение А и В
- break;
- case 7:
- A->print(const_cast<char*>("A: %s\n"));
- B->print(const_cast<char*>("B: %s\n")); //Вывод А и В как строк, используя встроенную функцию
- break;
- case 8:
- A->printint(const_cast<char*>("A: %i\n"));
- B->printint(const_cast<char*>("B: %i\n")); //Вывод А и В как чисел, тоже через встр-ю ф-ю
- break;
- case 9:
- A->printdbl(const_cast<char*>("A: %f\n"));
- B->printdbl(const_cast<char*>("B: %f\n"));
- break; //Что-то это мне напоминает...
- case 10: break; // Чтобы при a=10 не соскочить на default:
- default: //Если a не принадлежит 1-10, то присваиваем 0, чтобы показать меню в начале цикла
- a = 0;
- break;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement