Класс строки
Class string {
public:
string (char what) ; // Инициализация литерой
string strcat(char * scource) // конкатенация области памяти до первого
string strcat(char what) // Добавление символа
void print_at (unsigned x,unsigned y) // вывод строки на экран в позиции с координатами x, y
private:
char * buf;
unsigned len;
};
PS
public:
string (char what) ;
class пишется с маленькой буквы!
#include <stdio.h>
#include <iostream.h>
#include <string.h>
class string {
private:
char * buf;
unsigned len;
public:
string(char what)
{
buf = new char[2];
len = 1;
buf[0] = what;
buf[1] = 0; //все строки должны заканчиватся нулем, иначе гюки при конкатенации обеспечены.
}
string strcat(char* source)
{
len += strlen(source);
::strcat(buf,source);
return *this;
}
string strcat(char what)
{
//вариант не самый лучший. Просто лень было искать как можно сделать более правильно. Правда тут фокус один получился. После вызова оператора new, затирается последняя букова слова test(в примере внизу). Если кто сможет обьяснить от чего, буду очень благодарен, а то на вскидку не совсем понятно, а копатся времени нет :(
char* tmp = new char[2];
len = 1;
tmp[0] = what;
tmp[1] = 0;
len++;
::strcat(buf,tmp);
return *this;
}
void print_at(unsigned x,unsigned y)
{
gotoxy(x,y);
cout<<buf;
}
};
void main()
{
clrscr();
char* test = "test";
string str('a');
str.strcat(test);
str.print_at(10,10);
str.strcat('t');
str.print_at(10,11);
getchar();
}
Я бы реализовал примерно так. Использовал Borland C++ 3.1 (вариант не самый лучший, но включать Visual C++ or Builder - лень :) ). Правда сам прототип класса - ну не очень хороший(или очень не хороший ;)).
Да, и присоединюсь к Ordos - можно было отформатировать код.
Надеюсь помог.
#include <stdio.h>
#include <iostream.h>
#include <string.h>
class string {
private:
char * buf;
unsigned len;
public:
string(char what)
{
buf = new char[2];
len = 1;
buf[0] = what;
buf[1] = 0; //все строки должны заканчиватся нулем, иначе гюки при конкатенации обеспечены.
}
string strcat(char* source)
{
len += strlen(source);
[COLOR="#ff0000"] ::strcat(buf,source);[/COLOR]
return *this;
}
string strcat(char what)
{
//вариант не самый лучший. Просто лень было искать как можно сделать более правильно. Правда тут фокус один получился. После вызова оператора new, затирается последняя букова слова test(в примере внизу). Если кто сможет обьяснить от чего, буду очень благодарен, а то на вскидку не совсем понятно, а копатся времени нет :(
char* tmp = new char[2];
len = 1;
tmp[0] = what;
tmp[1] = 0;
len++;
[COLOR="#ff0000"] ::strcat(buf,tmp);[/COLOR]
return *this;
}
void print_at(unsigned x,unsigned y)
{
gotoxy(x,y);
cout<<buf;
}
};
void main()
{
clrscr();
char* test = "test";
string str('a');
str.strcat(test);
str.print_at(10,10);
str.strcat('t');
str.print_at(10,11);
getchar();
}
Какой ужас.
#include "string.h"
#include "stdlib.h"
#include "conio.h"
class string
{
public:
string()
: pBuf(0), iLen(0)
{}
string(char C)
: pBuf(0), iLen(0)
{
set(C);
}
string(const char* inBuf)
: pBuf(0), iLen(0)
{
set(inBuf);
}
string(const string& s)
: pBuf(0), iLen(0)
{
set(*s, s.len());
}
string& set(const char* inBuf)
{
size_t inLen = ::strlen(inBuf);
if(realloc(inLen)) {
memmove(pBuf, inBuf, inLen);
pBuf[inLen] = 0;
}
return *this;
}
string& set(const char* inBuf, size_t inLen)
{
if(realloc(inLen)) {
memmove(pBuf, inBuf, inLen);
pBuf[inLen] = 0;
}
return *this;
}
string& set(char C)
{
if(realloc(1)) {
pBuf[0] = C;
pBuf[1] = 0;
}
return *this;
}
string& cat(const char* inBuf)
{
size_t iOldLen = iLen;
size_t inLen = ::strlen(inBuf);
if(realloc(inLen + iLen)) {
memmove(pBuf + iOldLen, inBuf, inLen);
pBuf[iLen] = 0;
}
return *this;
}
string& cat(char C)
{
size_t iOldLen = iLen;
if(realloc(iLen + 1)) {
pBuf[iOldLen] = C;
pBuf[iLen] = 0;
}
return *this;
}
const char* operator *()
{
return pBuf ? pBuf : "";
}
const char* operator *() const
{
return pBuf ? pBuf : "";
}
size_t len() const
{
return pBuf ? iLen : 0;
}
protected:
int realloc(size_t iNewLen)
{
if(pBuf) {
if(iNewLen) {
pBuf = (char*)::realloc(pBuf, iNewLen + 1);
} else {
::free(pBuf);
pBuf = 0;
}
} else if(iNewLen) {
pBuf = (char*)::malloc(iNewLen + 1);
}
if(iNewLen && !pBuf) {
// ошибка: память под строку не выделена.
}
iLen = iNewLen;
return pBuf ? 1 : 0;
}
char* pBuf;
size_t iLen;
};
int main()
{
string s = "Test One";
printf("1: %s\n", *s);
s.set("Test Two");
printf("2: %s\n", *s);
s.cat(" Two");
printf("2a: %s\n", *s);
s.set("Test Three", 7);
printf("3: %s\n", *s);
s.set('A');
printf("4: %s\n", *s);
return 0;
}
А почему бы не использовать функции С++?) Зачем выделять память при помощи аллоков, если есть new? )
#include "string.h"
#include "stdlib.h"
#include "conio.h"
class string
{
public:
string()
: pBuf(0), iLen(0)
{}
string(char C)
: pBuf(0), iLen(0)
{
set(C);
}
string(const char* inBuf)
: pBuf(0), iLen(0)
{
set(inBuf);
}
string(const string& s)
: pBuf(0), iLen(0)
{
set(*s, s.len());
}
string& set(const char* inBuf)
{
size_t inLen = ::strlen(inBuf);
if(realloc(inLen)) {
memmove(pBuf, inBuf, inLen);
pBuf[inLen] = 0;
}
return *this;
}
string& set(const char* inBuf, size_t inLen)
{
if(realloc(inLen)) {
memmove(pBuf, inBuf, inLen);
pBuf[inLen] = 0;
}
return *this;
}
string& set(char C)
{
if(realloc(1)) {
pBuf[0] = C;
pBuf[1] = 0;
}
return *this;
}
string& cat(const char* inBuf)
{
size_t iOldLen = iLen;
size_t inLen = ::strlen(inBuf);
if(realloc(inLen + iLen)) {
memmove(pBuf + iOldLen, inBuf, inLen);
pBuf[iLen] = 0;
}
return *this;
}
string& cat(char C)
{
size_t iOldLen = iLen;
if(realloc(iLen + 1)) {
pBuf[iOldLen] = C;
pBuf[iLen] = 0;
}
return *this;
}
const char* operator *()
{
return pBuf ? pBuf : "";
}
const char* operator *() const
{
return pBuf ? pBuf : "";
}
size_t len() const
{
return pBuf ? iLen : 0;
}
protected:
int realloc(size_t iNewLen)
{
if(pBuf) {
if(iNewLen) {
pBuf = (char*)::realloc(pBuf, iNewLen + 1);
} else {
::free(pBuf);
pBuf = 0;
}
} else if(iNewLen) {
pBuf = (char*)::malloc(iNewLen + 1);
}
if(iNewLen && !pBuf) {
// ошибка: память под строку не выделена.
}
iLen = iNewLen;
return pBuf ? 1 : 0;
}
char* pBuf;
size_t iLen;
};
int main()
{
string s = "Test One";
printf("1: %s\n", *s);
s.set("Test Two");
printf("2: %s\n", *s);
s.cat(" Two");
printf("2a: %s\n", *s);
s.set("Test Three", 7);
printf("3: %s\n", *s);
s.set('A');
printf("4: %s\n", *s);
return 0;
}
Спасибо, программа интересно, как сделать чтобы чтобы в классе в public было только имя функции, а описание этих функций шло после описания класса. Например String::String(char buf), чтобы они описывались вне тела класса?
{
public:
String(char buf);
};
String::String(char buf)
{
}
ЗЫ: Вобщето так и надо, описание в *.h а реализация в *.c/*.cpp
А почему бы не использовать функции С++?) Зачем выделять память при помощи аллоков, если есть new? )
А как же быть с realloc? Кто даст гарантию что пулы одинаковые? А вызывать realloc вместо delete+new все же эффективней, т.к. если блок может быть увеличен по месту, то копирование содержимого не нужно.
Спасибо за советы вроде что-то получилось
Как добавлять символ каждый раз символ, который пользователь вводит в строку?
Как добавлять символ каждый раз символ, который пользователь вводит в строку?
Не совсем ясна задача. Сформулируй четче.
И чего ты хочешь добиться этим? Есть подозрение что у тебя сам подход не верен.
И чего ты хочешь добиться этим? Есть подозрение что у тебя сам подход не верен.
Мне нужно реализовать 4 методы класса string любым способом в том классе который я описал:
public:
string (char what) ; // Инициализация литерой
string strcat(char * scource) // конкатенация области памяти до первого
string strcat(char what) // Добавление символа
void print_at (unsigned x,unsigned y) // вывод строки на экран в позиции с координатами x, y
private:
char * buf;
unsigned len;
};
вначале инициализацию строки литерой, конкатенация области памяти до первого, добавление символа в строку пользователем , вывод на экран строки. Главное чтобы результат выводился. И реализация функций класс вне тела класса, то есть сначал класс какой он у меня описан а потом функции описать, а в main результаты.
{
char c;
string s = 'C';
s.cat("String");
cout >> "Введите символ: ";
cin >> c;
s.cat(c);
s.print_at(...); // реализация приведена выше моего первого сообщения в теме
return 0;
}
{
char c;
string s = 'C';
s.cat("String");
cout >> "Введите символ: ";
cin >> c;
s.cat(c);
s.print_at(...); // реализация приведена выше моего первого сообщения в теме
return 0;
}
Доброе утро! Очень нужна ваша помощь!
Я реализовал класс со строками так, все вроде ничего, только я хочу чтобы если ещё раз вызвав конкатенацию, добавлять новое введенное мной слово в уже новое слово, а не в изначальное ( до первой попытки конкатенации) ??
#include "string.h"
#include "stdlib.h"
#include "conio.h"
#include "iostream.h"
class string
{
public:
string (char what) ;
string strcat(char * source);
string str(char what);
void print_at(unsigned x,unsigned y);
private:
char * buf;
unsigned len;
};
string::string(char what)
{ buf=new char[2];
len=1;
buf[0]=what;
buf[1]=0;
}
void string::print_at(unsigned x,unsigned y)
{ gotoxy(x,y);
cout <<buf;
}
string string::strcat (char * source)
{ len+=strlen(source);
::strcat(buf, source);
return *this;
}
string string::str(char what)
{
char *temp=buf;
len=1;
buf=new char[len+1];
strcpy(buf,temp);
::strcat(buf,temp);
// delete [] temp;
return *this;
}
void main()
{ int ans,x1,y1;
char what;
clrscr();
cout << "input word:";
while (ans!=3)
{ cout<<" 1 - Insert word" <<'\n';
cout<<" 2 - Concat word" <<'\n';
cout<<" 3 - Write word" <<'\n';
cin >> ans;
switch(ans)
{
case 1:
{ clrscr();
cout <<"Vvedite bukvy:"<<'\n';
cin >> what;
cout <<"Vvedite koord:"<<'\n';
cout <<"Vvedite x:"<<'\n';
cin >> x1;
cout <<"Vvedite y:"<<'\n';
cin >> y1;
string str(what);
str.str(what);
str.print_at(10,11);
break;
}
case 2:
{ clrscr();
char* test = "t";
string str('r');
cout <<"Vvedite slovo:"<<'\n';
cin >> test;
cout <<"Vvedite koord:"<<'\n';
cout <<"Vvedite x:"<<'\n';
cin >> x1;
cout <<"Vvedite y:"<<'\n';
cin >> y1;
str.strcat(test);
str.print_at(x1,y1);
str.strcat(test);
str.print_at(x1,y1+2);
break; }
case 3:
{
break;
}
}
} ;
getchar();
}