Я вам пакушать приніс.
Значить, зробив свою strlen, зветься Length.
Додав метод Remove, котрий видаляє в нашій стрічці непотрібну підстроку.
Намучався я з ним... основною проблемою було вірно підставляти індекси в циклах, плутався я там часто, під кінець щось накльоцав і воно запрацювало.
#include <cstdlib>
#include <iostream>
#include <cstdio>
class MyString
{
public:
MyString::MyString(char* str)
{
int length = Length(str);
char* s1 = new char[length+1];
for (int i = 0; i < length; i++)
{
s1[i] = str[i];
}
s1[length] = '\0';
MyString::str = s1;
}
MyString::~MyString()
{
delete[] str; //очищуємо місце, котре виділялось під оті ваші стрічки
}
friend std::ostream& operator<<(std::ostream& os, const MyString& ms);
void operator+=(char* str)
{
int length = Length() + Length(str); // отримуємо довжину нової строки
char *s = new char[length+1]; // для термінатора
for (int i = 0; i < Length(); i++)// записуємо в нову строку те, що вже було
{
s[i] = MyString::str[i];
}
for (int i = 0; i < Length(str); i++)// дописуємо те, що треба додати
{
s[i + Length()] = str[i];
}
delete[] MyString::str;
MyString::str = s;// присвоюємо старому вказівнику на стару
MyString::str[length] = '\0'; //- це термінатор
}
void Remove(char* charsToRemove)
{
int index = 0;
std::cout << "Remove's entry..." << std::endl;
int lengthToRemove = Length(charsToRemove); // дізнаємось про довжину строки, котру треба видалити
std::cout << "Length to remove: " << lengthToRemove << std::endl;
for (int i = 0; i < Length(); i++) //починається цикл пошуку потрібної підстроки в нашій головній стрічці
{
for (int j = 0; j < lengthToRemove; j++) //перевірка, чи співпадає поточний знак головної строки - першому знаку строки для видалення
{
if (str[i] != charsToRemove[j])// якщо не співпадає, то прериваємо цей підцикл, та йдемо далі по головній стрічці
{
std::cout << "Wrong character comparsion:" << str[i] << " and " << charsToRemove[j] << std::endl;
break;
}
else // якщо співпадає, то йдемо далі
{
if (j == 0) // якщо поточний знак головної строки співпадає саме з першим знаком підстроки для видалення
{
index = i; // запам'ятовуємо індекс цього знаку (можливо, цей індекс вказує на початок підстроки)
}
std::cout << "Something found... " << j+1 << " need all "<<lengthToRemove << std::endl;
if (i < Length()) //якщо ми не в кінці головної строки
{
i++; //то збільшуємо індекс головного циклу, таким чином ми йдемо до перевірки наступного знаку головної строки
}
else
{
break; // якщо ж ми не знайшли цілу підстроку, то капець, прериваємо цикл
}
if (j == lengthToRemove - 1) //якщо ми знайшли цілу підстроку в нашій головній стрічці
{
std::cout << "I have got it!" << std::endl;
int newStrLength = Length() - lengthToRemove; // рахуємо довжину нової строки (якою вона буде після операції видалення)
std::cout <<"New string will have length: "<< newStrLength << std::endl;
char* newStr = new char[newStrLength+1]; // виділяємо пам'ять під цю строку, +1 для ТЕРМІНАТОРА!
std::cout << "First cycle has going on" << std::endl;
if (index > 0){ // якщо індекс початку підстроки більше нуля
for (int k = 0; k < index; k++) //цей цикл буде заповнювати нову підстроку тими знаками, котрі йдуть перед нею в головній стрічці
{
std::cout << "k is: " << k << " index is: " << index << std::endl;
std::cout << "At " << k << " index we have: " << str[k] << std::endl;
newStr[k] = str[k];
}
std::cout << "Second cycle has going on" << std::endl;
for (int l = index; l < Length()-((lengthToRemove-2)+index); l++) // а цей цикл заповнює нову підстроку знаками, що йдуть після підстроки в головній стрічці
{
std::cout << "At " << l << " index we have: " << str[l+index+(lengthToRemove-2)] << std::endl;//я не знаю, як воно працює, просто натикав щось навмання =(
newStr[l] = str[l + index + (lengthToRemove - 2)];
}
}
else //якщо ж підстрока починається з 0 індексу в головній стрічці
{
for (int h = 0; h < newStrLength; h++)//цей цикл просто заповнює нову строку тим, що йде після підстроки в головній стрічці
{
std::cout << "At " << h << " index we have: " << str[h+lengthToRemove] << std::endl;
newStr[h] = str[h + lengthToRemove];
}
}
newStr[newStrLength] = '\0'; // ставимо ТЕРМІНАТОРА!
delete[] str; //звільнюємо місце старої стрічки
str = newStr; //запам'ятовуємо посилання на нову
std::cout << "Done!" << std::endl;
}
}
}
}
}
int Length()
{
int i = 0;
while (str[i]!='\0')
{
i++;
}
return i;
}
private:
char *str;
int Length(char* str)
{
int i = 0;
while (str[i] != '\0')
{
i++;
}
return i;
}
};
std::ostream& operator<<(std::ostream& os, const MyString& ms)
{
os << ms.str;
return os;
}
int main()
{
MyString mys = "abcde";
mys.Remove("abc");
std::cout << mys << std::endl;
std::cout << "Length: " << mys.Length() << std::endl;
system("pause >> void");
}
Тільки от воно видаляє лише першу знайдену підстроку.
Майбуть, час для рекурсії?