class StrRus
{
.....
rusStr(char *s = "")
{
stroka=filter(s);
[COLOR="Red"]delete[] str;[/COLOR]
}
char* filter(char* s)
{
....
char* str=new char[strlen(s)+1];
....
return str;
}
}
[c++] собственный класс строк
Разработайте класс. для представления строки,
которая может содержать только русские символы.
Перегрузите для этого класса следующие операторы: +, +=, [].
в качестве входных данных используйте текстовые файлы.
Фильтрацию строки сделала, но есть один вопрос:
Код:
почему str не удаляется в любом из методов класса включая деструктор и конструктор?? (пишу там где красным и в любом из других методов) выдает ошибки:
error C2065: 'str' : undeclared identifier
error C2541: delete : cannot delete objects that are not pointers
Как в таком случае удалить str в том методе откуда вызывается filter ?
Цитата: v0lkan0
Код:
stroka=filter(s);
[COLOR="Red"]delete[] str;[/COLOR]
[COLOR="Red"]delete[] str;[/COLOR]
в stroka записывается указатель на первый символ того что выдаёт filter()
строка не копируется при этом.
поэтому если что-то и нужно удалять - то это то что лежало в stroka раньше
Код:
delete[] stroka;
stroka=filter(s);
stroka=filter(s);
Во первых это конструктор и stroka является пустой.
Во вторых если я сделаю delete[] stroka; то записать инфу из filter(s) я уже не смогу. (винда выдает ошибку и просит закрыть приложение, некоректная работа с памятью)
Я просто спрашиваю, как мне удалить str не в том методе в котором она объявлена, а в том в котором она используется. Такое вообще в принципе должно быть реально, только у меня не получается. Наверное все дело в зоне видимости переменных. Но все таки КАК ЕЕ УДАЛИТЬ???
у тебя str и stroka - указатели на одну и туже строку!
если удалить str, то удалится и stroka.
Код:
... char* filter(char* s)
{
....
char* str=new char[strlen(s)+1];
....
return str;
}...
{
....
char* str=new char[strlen(s)+1];
....
return str;
}...
Эту функцию тебе надо переделать.
Цитата: m_Valery
Вот этой твой кусок кода неправильный - memory leak!
Эту функцию тебе надо переделать.
Код:
... char* filter(char* s)
{
....
char* str=new char[strlen(s)+1];
....
return str;
}...
{
....
char* str=new char[strlen(s)+1];
....
return str;
}...
Эту функцию тебе надо переделать.
Обрати внимание - единственное место, где вызывается функция filter, это конструктор rusStr. Адрес выделенной памяти возвращается конструктору:
Код:
stroka=filter(s);
и тот сохраняет ее в stroka, а stroka освобождается в деструкторе (v0lkan0, я прав? В деструкторе освобождаешь ее?). Никакого мемори-лика.
Чтобы было понятнее, давайте представим себе такой код:
Код:
char* str=new char[strlen(s)+1];
char *stroka = str;
delete[] stroka;
[color=red]delete[] str;[/color] // ЭТО - ЛИШНЕЕ!
char *stroka = str;
delete[] stroka;
[color=red]delete[] str;[/color] // ЭТО - ЛИШНЕЕ!
v0lkan0, выделенную тобой красную строку вообще удали. Не нужна она.
P. S. этот код (один-в-один) уже обсуждался недавно в какой-то теме. Почему не продолжили обсуждение там? Зачем новую тему создавать?
Код:
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string>
#include <windows.h>
using namespace std;
class rusStr
{
char *stroka;
int len;
public:
rusStr(char *s = "") {
stroka=filter(s);
len=strlen(stroka);
}
rusStr(rusStr &str)
{
len=str.len;
stroka=new char[len+1];
strcpy(stroka,str.stroka);
}
~rusStr() {delete[] stroka;}
void get()
{
[COLOR="Green"]cout<<stroka<<endl;[/COLOR]
[COLOR="Navy"]char* x;
x=new char[strlen(stroka)+1];
CharToOem(stroka,x);
cout<<x<<endl;
delete[] x;[/COLOR]
}
rusStr operator+(const rusStr str)
{
rusStr s;
s.len=len+str.len;
s.stroka=new char[s.len+1];
strcpy(s.stroka,stroka);
strcat(s.stroka,str.stroka);
[COLOR="Red"]cout<<s.stroka<<endl;[/COLOR]
return s;
}
[COLOR="Purple"]/*
rusStr operator+(const rusStr str)
{
char* s1;
s1=new char[len+str.len+1];
strcpy(s1,stroka);
strcat(s1,str.stroka);
cout<<s1<<endl;
return s1;
}*/ [/COLOR]
char* filter(char* s)
{
char* str;
int len=strlen(s);
int j=0;
int i=0;
while(i<len)
{
if(((s>='а') && (s<='я')) || ((s>='А') && (s<='Я')))
{
j++;
}
if(s=='\n')
len--;
i++;
}
str=new char[j+1];
j=0;
i=0;
len=strlen(s);
while(i<len)
{
if(((s>='а') && (s<='я')) || ((s>='А') && (s<='Я')))
{
str[j]=s;
j++;
}
if(s=='\n')
len--;
i++;
}
str[j]=0;
return str;
}
};
int main()
{
rusStr a("qweприветqwe"), b("213мир23"), c=a;
a=a+b;
a.get();
return 0;
}
#include <cstdlib>
#include <fstream>
#include <string>
#include <windows.h>
using namespace std;
class rusStr
{
char *stroka;
int len;
public:
rusStr(char *s = "") {
stroka=filter(s);
len=strlen(stroka);
}
rusStr(rusStr &str)
{
len=str.len;
stroka=new char[len+1];
strcpy(stroka,str.stroka);
}
~rusStr() {delete[] stroka;}
void get()
{
[COLOR="Green"]cout<<stroka<<endl;[/COLOR]
[COLOR="Navy"]char* x;
x=new char[strlen(stroka)+1];
CharToOem(stroka,x);
cout<<x<<endl;
delete[] x;[/COLOR]
}
rusStr operator+(const rusStr str)
{
rusStr s;
s.len=len+str.len;
s.stroka=new char[s.len+1];
strcpy(s.stroka,stroka);
strcat(s.stroka,str.stroka);
[COLOR="Red"]cout<<s.stroka<<endl;[/COLOR]
return s;
}
[COLOR="Purple"]/*
rusStr operator+(const rusStr str)
{
char* s1;
s1=new char[len+str.len+1];
strcpy(s1,stroka);
strcat(s1,str.stroka);
cout<<s1<<endl;
return s1;
}*/ [/COLOR]
char* filter(char* s)
{
char* str;
int len=strlen(s);
int j=0;
int i=0;
while(i<len)
{
if(((s>='а') && (s<='я')) || ((s>='А') && (s<='Я')))
{
j++;
}
if(s=='\n')
len--;
i++;
}
str=new char[j+1];
j=0;
i=0;
len=strlen(s);
while(i<len)
{
if(((s>='а') && (s<='я')) || ((s>='А') && (s<='Я')))
{
str[j]=s;
j++;
}
if(s=='\n')
len--;
i++;
}
str[j]=0;
return str;
}
};
int main()
{
rusStr a("qweприветqwe"), b("213мир23"), c=a;
a=a+b;
a.get();
return 0;
}
З.Ы. Фиолетовым выделен еще один вариант перегрузки.
Помогите пожалуйста разобраться в этих указателях и выделении памяти. Вообще моя задача звучит так:
Разработайте класс rusStr. для представления строки,
которая может содержать только русские символы.
Перегрузите для этого класса следующие операторы: +, +=, [].
в качестве входных данных используйте текстовые файлы
и подскажите что значит перегрузить [] что именно они должны делать? проверять на конец строки? или что??
Цитата: v0lkan0
Проблема в следующем: в перегрузке operator+ у меня все нормально работает и коректно слаживает две строки объекта что подтверждает вывод на экран (красным), но после return s1; содержимое строки куда-то исчезает и метод get выводит совершенно другую строку (точнее мусор какой-то) причем (зеленым) выводит один мусор, а (синим) уже другой.
Перегрузите для этого класса следующие операторы: +, +=, [].
в качестве входных данных используйте текстовые файлы
и подскажите что значит перегрузить [] что именно они должны делать? проверять на конец строки? или что??
Код:
rusStr operator+(const rusStr str)
{
rusStr s;
s.len=len+str.len;
s.stroka=new char[s.len+1];
strcpy(s.stroka,stroka);
strcat(s.stroka,str.stroka);
[COLOR=Red]cout<<s.stroka<<endl;[/COLOR]
return s;
}
int main()
{
rusStr a("qweприветqwe"), b("213мир23"), c=a;
[SIZE=5][COLOR=Red]a=a+b;[/COLOR][/SIZE]
a.get();
return 0;
}
{
rusStr s;
s.len=len+str.len;
s.stroka=new char[s.len+1];
strcpy(s.stroka,stroka);
strcat(s.stroka,str.stroka);
[COLOR=Red]cout<<s.stroka<<endl;[/COLOR]
return s;
}
int main()
{
rusStr a("qweприветqwe"), b("213мир23"), c=a;
[SIZE=5][COLOR=Red]a=a+b;[/COLOR][/SIZE]
a.get();
return 0;
}
в качестве входных данных используйте текстовые файлы
и подскажите что значит перегрузить [] что именно они должны делать? проверять на конец строки? или что??
Код:
{
char* getStr() {return stroka;}
rusStr operator+(const rusStr& rhs)
{
rusStr temp;
temp.len = len + rhs.len;
temp.stroka = new char[temp.len + 1];
strcpy(temp.stroka,stroka);
strcat(temp.stroka,rhs.stroka);
return temp;
}
rusStr& operator+=(const rusStr& rhs)
{
int totalLen = len + rhs.len;
char* totalStroka = new char[totalLen + 1];
strcpy(totalStroka,stroka);
strcat(totalStroka,rhs.stroka);
delete[] stroka;
stroka = totalStroka;
return *this;
}
rusStr& operator=(const rusStr& rhs)
{
if(this == &rhs) return *this;
delete [] stroka;
stroka = new char[rhs.len + 1];
strcpy(stroka, rhs.stroka);
len = rhs.len;
return *this;
}
char& operator[](int index)
{
if(index>=0 && index < len)
{
return stroka[index];
}
else
{
//кинуть исключение или еще что-нибудь
}
}
}
char *rus_str(const char *in,char *out)
{
if (CharToOemA(in, out))
return out;
else
return 0;
}
int main()
{
rusStr a("qweприветqwe"), b("213мир23"), c;
char *str = new char[100];
cout << rus_str(a.getStr(),str) << endl;
cout << rus_str(b.getStr(),str) << endl;
c = a + b;
cout << rus_str(c.getStr(),str) << endl;
c += b;
cout << rus_str(c.getStr(),str) << endl;
cout << c[1] << endl;
return 0;
}
char* getStr() {return stroka;}
rusStr operator+(const rusStr& rhs)
{
rusStr temp;
temp.len = len + rhs.len;
temp.stroka = new char[temp.len + 1];
strcpy(temp.stroka,stroka);
strcat(temp.stroka,rhs.stroka);
return temp;
}
rusStr& operator+=(const rusStr& rhs)
{
int totalLen = len + rhs.len;
char* totalStroka = new char[totalLen + 1];
strcpy(totalStroka,stroka);
strcat(totalStroka,rhs.stroka);
delete[] stroka;
stroka = totalStroka;
return *this;
}
rusStr& operator=(const rusStr& rhs)
{
if(this == &rhs) return *this;
delete [] stroka;
stroka = new char[rhs.len + 1];
strcpy(stroka, rhs.stroka);
len = rhs.len;
return *this;
}
char& operator[](int index)
{
if(index>=0 && index < len)
{
return stroka[index];
}
else
{
//кинуть исключение или еще что-нибудь
}
}
}
char *rus_str(const char *in,char *out)
{
if (CharToOemA(in, out))
return out;
else
return 0;
}
int main()
{
rusStr a("qweприветqwe"), b("213мир23"), c;
char *str = new char[100];
cout << rus_str(a.getStr(),str) << endl;
cout << rus_str(b.getStr(),str) << endl;
c = a + b;
cout << rus_str(c.getStr(),str) << endl;
c += b;
cout << rus_str(c.getStr(),str) << endl;
cout << c[1] << endl;
return 0;
}
Индексатор [] возвращает в твоем случае букву на определенной позиции.
Все операторы я перегрузил, смотри код (просто вставь кусками в свой код, надеюсь поймешь что куда вставлять), также немного по другому делал вывод на экран но ты уже сам разберешься что и как.
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string>
#include <windows.h>
using namespace std;
class rusStr
{
char *stroka;
int len;
public:
rusStr(char *s = "")
{
stroka=filter(s);
len=strlen(stroka);
}
rusStr(rusStr &str)
{
len=str.len;
stroka=new char[len+1];
strcpy(stroka,str.stroka);
}
~rusStr() {delete[] stroka;}
void get()
{
cout<<stroka<<endl;
char* x;
x=new char[strlen(stroka)+1];
CharToOem(stroka,x);
cout<<x<<endl;
delete[] x;
}
char* getStr() {return stroka}
rusStr operator+(const rusStr& rhs)
{
rusStr temp;
temp.len = len + rhs.len;
temp.stroka = new char[temp.len + 1];
strcpy(temp.stroka,stroka);
strcat(temp.stroka,rhs.stroka);
return temp;
}
rusStr& operator+=(const rusStr& rhs)
{
int totalLen = len + rhs.len;
char* totalStroka = new char[totalLen + 1];
strcpy(totalStroka,stroka);
strcat(totalStroka,rhs.stroka);
delete[] stroka;
stroka = totalStroka;
return *this;
}
rusStr& operator=(const rusStr& rhs)
{
if(this == &rhs) return *this;
delete [] stroka;
stroka = new char[rhs.len + 1];
strcpy(stroka, rhs.stroka);
len = rhs.len;
return *this;
}
/*
rusStr operator+(const rusStr str)
{
char* s1;
s1=new char[len+str.len+1];
strcpy(s1,stroka);
strcat(s1,str.stroka);
cout<<s1<<endl;
return s1;
}*/
/*
______________________________
*/
char& operator[](int index)
{
if(index>=0 && index < len)
{
return stroka[index];
}
else
{
//кинуть исключение или еще что-нибудь
}
}
char *rus_str (const char *in, char *out)
{
if (CharToOemA(in, out))
return out;
else
return 0;
}
/*
______________________________
*/
char* filter(char* s)
{
char* str;
int len=strlen(s);
int j=0;
int i=0;
while(i<len)
{
if(((s>='а') && (s<='я')) || ((s>='А') && (s<='Я')))
{
j++;
}
if(s=='\n')
len--;
i++;
}
{ str=new char[j+1];
j=0;
i=0;
len=strlen(s);
while(i<len)
{
if(((s>='а') && (s<='я')) || ((s>='А') && (s<='Я')))
{
str[j]=s;
j++;
}
if(s=='\n')
len--;
i++;
}
str[j]=0;
return str;
}
int main()
{
rusStr a("qweприветqwe"), b("213мир23"), c;
char *str = new char[100];
cout << rus_str(a.getStr(),str) << endl;
cout << rus_str(b.getStr(),str) << endl;
c = a + b;
cout << rus_str(c.getStr(),str) << endl;
c += b;
cout << rus_str(c.getStr(),str) << endl;
cout << c[1] << endl;
return 0;
}
}
:o:o:o
Доработанная программа здесь :
Вычислить сумму 1!+2!+3!+…+n! . Значение n вводится с клавиатуры;
Задача по теме: Организация приложений с несколькими потоками.
Класс TThread.
с++ Builder