Работа пользовательского класса string

253
01 июня 2018, 02:20

Ввод строки работает правильно вне switch, если хочу вызвать функцию через switch ,то после ввода строки зависает с сообщением "Прекращена работа ..." Подскажите в чем ошибка?

#include<iostream>
#include <cstring>
using namespace std;
class MyString
{
public:
friend std::istream& operator>> (std::istream& in, MyString& t);
friend std::ostream& operator<< (std::ostream& out, const MyString& t);
void get_input (std::istream& in);
//конструктор без параметров
MyString()
{
str = nullptr;
length = 0;
}
//конструктор с параметрами, при создании объекта класса необходимо перелать строку которую он будет хранить
MyString(const char *str)
{
length = strlen(str);// функция strlen получает количество символов в строке которую мы передаём в объект
// выделяем память для динамического массива где будет храниться наша строка 
// +1 символ так как нужно место в массиве под терминирующий 0
this->str = new char[length + 1];
// копируем символы строки в массив нашего класса
for (int i = 0; i < length; i++)
{
this->str[i] = str[i];
}
//закрываем строку терминирующим нулём
this->str[length] = '\0';
}
// деструктор, отвечает за освобождение ресурвов занятых объектом, вызывается при уничтожении объекта класса
~MyString()
{
delete[] this->str;
}
// конструктор копировании, необходим для создании точной копи объекта класса но в другой области памяти
MyString(const MyString &other)
{
length = strlen(other.str);
this->str = new char[length + 1];
for (int i = 0; i < length; i++)
{
this->str[i] = other.str[i];
}
this->str[length] = '\0';
}
// перегруженый оператор присваивания, вызывается когда необходимо присвоить значение одного объекта другому
MyString& operator =(const MyString &other)
{
// здесь логика похожа на ту которая реализована в конструкторе, за исключением того, что нам нужно позаботиться
// об освобождении ресурсов объекта если до копирования в него новой строки он уже содержал код 
//+ страндартный синтаксис перегрузки оператора =
if (this->str != nullptr)
{
delete[] str;
}
length = strlen(other.str);
this->str = new char[length + 1];
for (int i = 0; i < length; i++)
{
this->str[i] = other.str[i];
}
this->str[length] = '\0';
return *this;
}
//перегруженный оператор сложения, в текущей реализации класса String необходим для конкатенации строк
MyString operator+(const MyString &other)
{
//создаём новый пустой объект где будим хранить результат конкатенации строк и который будет результатом работы
// перегруженного оператора +
MyString newStr;
// получаем количество символов в обеих строках для конкатенации
int thisLength = strlen(this->str);
int otherLength = strlen(other.str);
newStr.length = thisLength + otherLength;
// выделяем место в динамической памяти под новую строку
newStr.str = new char[thisLength + otherLength + 1];
//копируем данные из 2х конкатенируемых строк в новую строку
int i = 0;
for (; i < thisLength; i++)
{
newStr.str[i] = this->str[i];
}
for (int j = 0; j < otherLength; j++, i++)
{
newStr.str[i] = other.str[j];
}
newStr.str[thisLength + otherLength] = '\0';
// возвращаем результат конкатенации
return newStr;
}
// выводит строку в консоль, в идеале для этого необходима перегрузка оператора «
void Print()
{
cout << str;
}
int Length()
{
return length;
}
bool operator ==(const MyString & other)
{
if (this->length != other.length)
{
return false;
}
for (int i = 0; i < this->length; i++)
{
if (this->str[i] != other.str[i])
{
return false;
}
}
return true;
}
bool operator !=(const MyString & other) 
{
return !(this->operator==(other));
}
char& operator [](int index) 
{
return this->str[index];
}
MyString(MyString &&other) 
{ 
this->length = other.length; 
this->str = other.str; 
other.str = nullptr; 
} 
private: 
// Указатель на массив char, хранит символы, которые мы передали в наш объект. 
char *str; 
int length; 
}; 
void MyString::get_input (std::istream& in)
{
    while (true)
    {
        char c = in.get ();
        if (c == '\n')
        {
            break;
        }
        if (length == 0)
        {
            length = 2;
        }
        else
        {
            ++length;
        }
        char* newStr = new char[length];
        if (str != NULL)
        {
            strcpy (newStr, str);
        }
        newStr[length-2] = c;
        newStr[length-1] = '\0';
        delete[] str;
        str = newStr;
    }
}

std::istream& operator>> (std::istream& in, MyString& t)
{
    t.get_input (in);
    return in;
}
std::ostream& operator<< (std::ostream& out, const MyString& t)
{
    out << t.str;
    return out;
}
void sumstr()
{
    MyString st;
    MyString zt;
    MyString tt;
    cout<<"[1] = ";
    cin >> st;
    cout<<endl;
    cout<<"[2] = ";
    cin >> zt;
    cout<<endl;
    tt = st + zt;
    cout<<"[1] + [2] = "<<tt<<endl;
}
int main() 
{ 
    sumstr();
    int num;
    do{
    cin>>num;
    switch(num)
    {
        case 1: sumstr();
        break;
        case 2: exit(0);
    }
    }while(num>0);
system("pause"); 
return 0; 
}
Answer 1

Воспользуйтесь

cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n') 

для сброса буфера после cin>>num - в буфере остается несчитанный '\n'...

READ ALSO
Инъекция DLL в свой процесс C++

Инъекция DLL в свой процесс C++

Учу С++Интересен способ инъекции DLL в свой процесс

224
Как преобразовать тип bool в enum?

Как преобразовать тип bool в enum?

Есть перечисление:

256
Можно ли как-либо обратиться к терминалу на mac os при помощи языка c++

Можно ли как-либо обратиться к терминалу на mac os при помощи языка c++

Например ввести команду ls, и считать список файлов в директории

183
Добавление и удаление значений в QVector

Добавление и удаление значений в QVector

Мне нужно написать функции которые добавляют и удаляют значения в QVector

206