Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Класс для работы со строками. 
:(
    Опции темы
Mal Hack
Дата 14.5.2006, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 2
Всего: 261



Задание написать класс вот такой:
Код
class String
{
//    private:

    public:
        int       Len;
        char * Str;
        String( void );
        String( char ch );
        String( char * s );
        String( char & s );

        char & operator [] ( int index );
        String & operator =  ( String & s );
        String & operator += ( String & s );
        String & operator +  ( String & s );
        // operator char * ();

        bool operator == ( String & s );
        bool operator <= ( String & s );
        bool operator >= ( String & s );
        bool operator <  ( String & s );
        bool operator >  ( String & s );

        char * GetString( void );
        int GetLength( void );
        String SubString( int StartIndex );
        String SubString( int StartIndex , int Length );
        int IndexOf( String & s );

        ~String();
};


Вот что есть:
Код
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>

class String
{
//    private:

    public:
        int       Len;
        char * Str;
        String( void );
        String( char ch );
        String( char * s );
        String( char & s );

        char & operator [] ( int index );
        String & operator =  ( String & s );
        String & operator += ( String & s );
        String & operator +  ( String & s );
        // operator char * ();

        bool operator == ( String & s );
        bool operator <= ( String & s );
        bool operator >= ( String & s );
        bool operator <  ( String & s );
        bool operator >  ( String & s );

        char * GetString( void );
        int GetLength( void );
        String SubString( int StartIndex );
        String SubString( int StartIndex , int Length );
        int IndexOf( String & s );

        ~String();
};

String::String( void )
{
    this -> Str = "";
    this -> Len = 0;
}

String::String( char ch )
{
    this -> Str = ( char * )ch;
    this -> Len = 1;
}

String::String( char * s )
{
    this -> Str = ( char * ) s;
    this -> Len = this -> GetLength();
}

String::String( char & s )
{
    this -> Str = & s;
    this -> Len = this -> GetLength();
}

int String::GetLength( void )
{
    return strlen( this -> Str );
}

char * String::GetString( void )
{
    return this -> Str;
}

bool String :: operator == ( String & s )
{
    return ( this -> Str == s.Str ) ? true : false;
}

bool String :: operator >= ( String & s )
{
    return ( this -> Str >= s.Str ) ? true : false;
}

bool String :: operator <= ( String & s )
{
    return ( this -> Str <= s.Str ) ? true : false;
}

bool String :: operator > ( String & s )
{
    return ( this -> Str > s.Str ) ? true : false;
}

bool String :: operator < ( String & s )
{
    return ( this -> Str < s.Str ) ? true : false;
}

String String::SubString( int StartIndex )
{
    String * s = new String( this -> GetString() );
    
    int i;

    this  -> Str = "";

    for( i = StartIndex ; i < s -> Len ; i++ )
    {
        this -> Str += s -> Str[ i ];
    }

    this -> Len = this -> GetLength();

    return * this;
}

String String::SubString( int StartIndex , int Length )
{
    int i;

    for( i = StartIndex ; i < Length ; i++ )
    {
        this -> Str[ i - StartIndex ] = this -> Str[ i ];
    }

    this -> Str[  this -> Len - StartIndex ] = '\0';
    this -> Len = this -> GetLength();

    return * this;
}

int String::IndexOf( String & s )
{
    return 0;
}

char & String::operator [] ( int index )
{
    if( index < 0 || index > this -> Len )
    {
        printf( "Неверный индекс i = %d" , index );
        exit( 0 );
    }

    return this -> Str[ index ];
}
/*
String::operator char * ()
{
    return this -> Str;
}
*/

String & String::operator + ( String & s )
{
    int i;

    for( i = 0 ; i < this -> Len ; i++ )
    {    s . Str[ i + s . Len ] = this -> Str[ i ];    }

    s . Len += this -> Len;

    return s;
}

String & String::operator += ( String & s )
{
    int i;

    String * st = new String( s . Str );

    for( i = 0 ; i < this -> Len ; i++ )
    {    s . Str[ i ] = this -> Str[ i ];    }

    for( i = 0 ; i < st -> Len ; i++ )
    {    s . Str[ i + this -> Len ] = st -> Str[ i ];    }

    s . Len += this -> Len;

    return s;
}

String & String::operator = ( String & s )
{
    s . Str = this -> Str;
    s . Len = this -> Len;

    return s;
}

String::~String()
{
    delete [] Str;
}

void main()
{
    String * Str1 , * Str2 , * Str3;

    Str1 = new String( "123456789" );
    Str2 = new String( "abcdefghi" );
    Str3 = new String();

    Str1 +=  Str2;

    printf( "Str1 = %s\nStr2 = %s\nStr3 = %s\n\n" , Str1 -> GetString() , Str2 -> GetString() , Str3 -> GetString() );

    //Str1 -> SubString( 5 );
    //Str2 -> SubString( 1 , 5 );

    //printf( "Str1 SubString( 5 ) = %s\nStr2 SubString( 1 , 5 ) = %s\n" , Str2 -> GetString() , Str3 -> GetString() );

    getch();
    exit(0);

    //Str3 += (char & ) "12345";

    //printf( "Str3 += 12345 = %s\n" , Str3 -> GetString() );

    //Str2 = Str2 + ( char * ) ( ( char & ) "12345" );

    //printf( "Str3 += 12345 = %s\n" , Str3 -> GetString() );

    getch();
}


Видимо я, ввиду того, что впервые с VS.NET работаю и с С++ на таком уровне, не могу понять как грамтно сделать перегрузку. Т.е. идет несоответствие типов. Начиная с +=, + и SubString.
Выдает: Access Violation или 
1> error C2297: '+=' : illegal, right operand has type 'String *'
1> error C2114: '+=' : pointer on left; needs integral value on right
На строке 
    Str1 +=  Str2;

Как правильно сделать? Вроде бы с примерами из книжки Поплавской совпадает... 
PM ICQ   Вверх
chipset
Дата 14.5.2006, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 27
Всего: 165



Цитата(Mal Hack @  14.5.2006,  07:43 Найти цитируемый пост)
1> error C2297: '+=' : illegal, right operand has type 'String *'
1> error C2114: '+=' : pointer on left; needs integral value on right
На строке 
    Str1 +=  Str2;

Прибавляешь указатель к указателю. Нужно так: (*Str1) += (*Str2) либо как-нибудь вот так
Str1->operator +=(*Str2);   


--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Mal Hack
Дата 14.5.2006, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 2
Всего: 261



ВОт функция перегрузки оператора +=
Код
String & String::operator += ( String & s )
{
    int i;

    String * st = new String( s . Str );

    //printf("%s" , s[5] );
    //getch();
    for( i = 1 ; i < this->Len ; i++ )
    {    
        //s.Str[ i ] = this[ i ];     <<<<<<<<<<<<<<<<<<<
        printf( "%s\n", s . Str[ i ] );
        getch();
    }
    for( i = 0 ; i < st -> Len ; i++ )
    {    s . Str[ i + this -> Len ] = st -> Str[ i ];    }

    s . Len += this -> Len;

    return s;
}

В помеченной строчке возникает ошибка при запуске:
Код
Unhandled exception at 0x10227c2f (msvcr80d.dll) in String.exe: 0xC0000005: Access violation reading location 0x00000066.

При этом, символы, если обращаться как  s[5] или this[i] читаются.
Но записать я не могу. В чем я ошибаюсь? 
PM ICQ   Вверх
bsa
Дата 14.5.2006, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Ты неправильно определяещь этот метод, надо:
Код
String & String::operator += ( const String & s )

Таким образом ты не имеешь права менять переменную справа от оператора. Не забывай, что String & s  и String s - это разные вещи.
Этот метод я бы реализовал так:
Код
String& String::operator += (const String & s ) {
     Str = (char*) realloc( Str, s.Len + Len);
     memcpy(Str + Len, s.Str, s.Len);
     Len += s.Len;
     return *this;
}
  

Это сообщение отредактировал(а) bsa - 14.5.2006, 21:11
PM   Вверх
Joss
Дата 14.5.2006, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 103
Регистрация: 19.3.2006

Репутация: 1
Всего: 1



А почему модифицируется s? Ведь S1 += S2 - сокращенная запись S1 = S1 + S2.  А вообще лучше написать так:

Код

String & String::operator += ( const String & s )
{
    *this = *this + s;
    return *this;
}


При этом дотжны быть перегружены операции = и +.

А ошибка, на мой взгляд, вот почему: в выделеной строке индексируется указатель на String. Его сначала нужно разыменовать:
Код

  (*this)[i]         //может так?


Кстати обращаться через this не обязательно. Можно просто Str[i]. 
PM MAIL   Вверх
Mal Hack
Дата 14.5.2006, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 2
Всего: 261



bsa, вся проблема в том, что сделать надо жестко по заданию... Хотя я уже давно понял, что оно - корявое. 
PM ICQ   Вверх
MAKCim
Дата 14.5.2006, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Код

String& operator+(String& s)

не верен семантически
лучше operator+ (-,...) реализовывать через operator+= (-=,...)
и делать friend-ом если невозможно работать через интерфейс
+лучше параметры передавать по const-ссылке

Добавлено @ 21:23 
Joss опередил 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bsa
Дата 14.5.2006, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Mal Hack, у тебя в задании реализация записана?!? Это вряд ли. Если же ты про const, то можно его опустить, но ты должен иметь в виду, что += в данном контексте не должна менять свой параметр. А ты пытался его поменять, тем более, что переменная цикла i у тебя шла по диапазону допустимому для this, но не для s.
И вообще, зачем так мудрить? Алгоритм сложный, перегруженый. А работы всего на 4 строчки: выделить дополнительную память, скопировать добавляемую строку в конец, увеличить размер текущей строки, вернуть ссылку на себя. 
PM   Вверх
bel_nikita
Дата 14.5.2006, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



Mal Hack,
может на реализацию MFC CString взгляни ( ...\MFC\SRC\STRCORE.CPP ).
и вместо for(i=...) старайся memcpy использовать 


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
MAKCim
Дата 15.5.2006, 07:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

может на реализацию MFC CString взгляни

или std::string  smile  


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
UnrealMan
Дата 15.5.2006, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Ужас-то какой... Констукторы написаны неправильно, операторы сравнения тоже. Тут вам и утечки памяти и удаление несуществующей... Короче, полный комплект. Наверно, проще не исправлять здешние ошибки, а написать заново весь класс. 
PM MAIL   Вверх
UnrealMan
Дата 16.5.2006, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Код
class String
{
    char *pData; // данные строки
    int len; // длина строки
    int size; // Размер памяти, выделенной под строку.
    // можно было б обойтись len, но тогда работать всё это будет медленно

    char *Allocator();
    char *Allocator(int);
    void Deallocator();

public:
    String();
    String(const String &s);
    String(const char *s);
    String(char ch);

    ~String();

    char &operator [](int index);
    char &operator *();

    String &operator =(const String &s);
    String &operator +=(const String &s);

    String operator +(const String &s);

    bool operator ==(const String &s);
    bool operator !=(const String &s);
    bool operator <=(const String &s);
    bool operator >=(const String &s);
    bool operator <(const String &s);
    bool operator >(const String &s);

    char *GetString();
    int GetLength();
    String SubString(int startIndex);
    String SubString(int startIndex, int length);
    int IndexOf(const String &s);
};

Код
// функция, контроля и выделения дополнительной памяти
// под данные строки
char *String::Allocator()
{
    return len<size ? pData : (pData = Realloc_(pData, size=len*2, char));
    // если памяти не хватает, выделяем примерно вдвое больше, чем требуется.
    // такая стратегия позволяет в ряде случаев избежать многократного вызова
    // realloc, что может существенно сэкономить время выполняемых вычислений
}

// функция выделения памяти под данные строки
char *String::Allocator(int)
{
    return MAlloc_(pData, size=len+1, char);
}

// функция освобождения памяти, занятой под данные строки
void String::Deallocator()
{
    Free_(pData);
}


String::String()
{
    len = 0;
    *Allocator(0) = 0; // обнуление строки
}

String::String(const String &s)
{
    len = s.len;
    strcpy(Allocator(0), s.pData); // выделение памяти под строку с
    // последующим копированием данных из строки s в текущую (this)
    // cтроку
}

String::String(const char *s)
{
    len = strlen(s);
    strcpy(Allocator(0), s); // аналогично пред.
}

String::String(char ch)
{
    len = 1;
    *Allocator(0) = ch; // выделение памяти под строку с
    // последующим назначением нулевому элементу pData значения ch
    pData[1] = 0; // обнуление 1-го элемента pData
    // (всякая строка должна оканчиваться нулём)
}

String::~String()
{
    Deallocator();
}

char &String::operator [](int index)
{
    return 0<=index && index<len ? pData[index] : pData[len];
    // при допустимом индексе возвращается pData[index]
    // при недопустимом индексе возвращается 0
}

char &String::operator *()
{
    return *pData;
}

String &String::operator =(const String &s)
{
    len = s.len;
    strcpy(Allocator(), s.pData); // см. конструктор для const String &s
    return *this;
}

String &String::operator +=(const String &s)
{
    len += s.len;
    strcpy(Allocator()+len-s.len, s.pData); // выделение по необходимости доп. памяти
    // и копирование строки s в конец текущей
    return *this;
}

String String::operator +(const String &s)
{
    String result = *this;
    return result += s;
}

bool String::operator ==(const String &s)
{
    return len==s.len && !strcmp(pData, s.pData);
    // здесь сначала сравниваются длины строк
    // если они не совпадают, то возвращается false;
    // ежели совпадают, то сравниваются сами строки
    // (посредством strcmp), результат strcmp отрицается
    // (поскольку эта ф-я истинна, когда строки не совпадают)
    // и возвращается return
}

bool String::operator !=(const String &s)
{
    return len!=s.len || strcmp(pData, s.pData);
    // здесь сначала сравниваются длины строк
    // если они не совпадают, то возвращается true;
    // ежели совпадают, то сравниваются сами строки
    // и результат strcmp возвращается return
}

bool String::operator <=(const String &s)
{
    return len<=s.len && !strncmp(pData, s.pData, len);
    // strncmp подобно strcmp тоже сравнивает строки, но не
    // целиком, а только то количество начальных символов строк,
    // что задано в её третьем параметре
}

bool String::operator >=(const String &s)
{
    return len>=s.len && !strncmp(pData, s.pData, s.len);
}

bool String::operator <(const String &s)
{
    return len<s.len && !strncmp(pData, s.pData, len);
}

bool String::operator >(const String &s)
{
    return len>s.len && !strncmp(pData, s.pData, s.len);
}

char *String::GetString()
{
    return pData;
}

int String::GetLength()
{
    return len;
}

String String::SubString(int startIndex)
{
    String result;
    if (startIndex<0 || len<=startIndex)
        return result; // при недопустимом startIndex возвращается пустая строка

    result.len = len - startIndex;
    strcpy(result.Allocator(), pData+startIndex);
    // выделяем нужное кол-во памяти под данные строки result,
    // копируем в память, на которую указывает result.pData, содержимое
    // текущей (this) строки со смещением startIndex.
    return result;
}

String String::SubString(int startIndex, int length)
{
    String result;
    if (startIndex<0 || len<startIndex+length || length<0)
        return result; // при недопустимой паре (startIndex, length)
    // возвращается пустая строка

    result.len = length;
    strncpy(result.Allocator(), pData+startIndex, length);
    result.pData[length] = 0;
    return result;
}

int String::IndexOf(const String &s)
{
    int cmpMaxStartIndex = len-s.len;
    for (int i=0; i<=cmpMaxStartIndex; i++)
        if (!strncmp(pData+i, s.pData, s.len)) // как только обнаруживаем вхождение s
            // в текущую строку
            return i; // возвращаем индекс символа
    return -1; // если вхождений нет, то возвращается -1
}

Код
#define MAlloc_(p, size, T) \
    ( p = (T *)malloc((size)*sizeof(T)) )
#define Realloc_(p, newSize, T) \
    (T *)realloc(p, (newSize)*sizeof(T))
#define Free_(p)  free(p)
   

Это сообщение отредактировал(а) UnrealMan - 16.5.2006, 21:29
PM MAIL   Вверх
Mal Hack
Дата 16.5.2006, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 2
Всего: 261



UnrealMan, это учебная прога и сдавать ее не мне... Человек этого  не объяснит... 
PM ICQ   Вверх
bsa
Дата 16.5.2006, 20:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



А то что есть - работать не будет. Придется выбирать. smile 
PM   Вверх
UnrealMan
Дата 16.5.2006, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Добавил чуток комментариев. Может, так понятней будет :-) 
PM MAIL   Вверх
Mal Hack
Дата 21.5.2006, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 2
Всего: 261



bsa, как в твоем примере надо делать вызов?
Пишу:
Код
Str1  += (String &)Str2;

Получаю ошибку:
Цитата
error C2677: binary '+=' : no global operator found which takes type 'String' (or there is no acceptable conversion)
 
PM ICQ   Вверх
Mal Hack
Дата 29.5.2006, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 2
Всего: 261



chipsetbsaJossUnrealMan, благодарю за помощь.

Вот что получилось:

Код
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>

class String
{
    private:
        int       Len;
        char * Str;
    public:
        String( void );
        String( char ch );
        String( char * s );
        String( char & s );

        char & operator [] ( int index );

        String & operator =  ( const String & s );
        String & operator += ( const String & s );
        String & operator +  ( const String & s );

        bool operator == ( const String & s );
        bool operator != ( const String & s );
        bool operator <= ( const String & s );
        bool operator >= ( const String & s );
        bool operator <  ( const String & s );
        bool operator >  ( const String & s );

        char * GetString( void );
        int GetLength( void );
        String & SubString( int StartIndex );
        String & SubString( int StartIndex , int Length );
        int IndexOf( const String & s );

        ~String();
};

String::String( void )
{
    this->Str = "";
    this->Len = 0;
}

String::String( char ch )
{
    this->Str = (char *) malloc( sizeof( char ) );
    this->Str = ( char * )ch;
    this->Len = 1;
}

String::String( char * s )
{
    this->Str = (char *) calloc( strlen( s ) , sizeof( char ) );
    this->Str = ( char * ) s;
    this->Len = this -> GetLength();
}

String::String( char & s )
{
    this->Str = (char *) calloc( strlen( &s ) , sizeof( char ) );
    this->Str = & s;
    this->Len = this -> GetLength();
}

int String::GetLength( void )
{
    return strlen( this -> Str );
}

char * String::GetString( void )
{
    return this -> Str;
}

bool String::operator == ( const String & s )
{
    return this->Len == s.Len && 0 == strcmp( this->Str , s.Str );
}

bool String::operator != ( const String & s )
{
    return this->Len != s.Len || 0 != strcmp( this->Str , s.Str );
}

bool String::operator >= ( const String & s )
{
    return this->Len >= s.Len && 0 <= strncmp( this->Str , s.Str , this->Len );
}

bool String::operator <= ( const String & s )
{
    return this->Len <= s.Len && strncmp( this->Str , s.Str , this->Len ) <= 0;
}

bool String::operator >( const String & s )
{
    return this->Len > s.Len && 0 < strncmp( this->Str , s.Str , this->Len );
}

bool String::operator < ( const String & s )
{
    return this->Len < s.Len && 0 > strncmp( this->Str , s.Str , this->Len );
}

String & String::SubString( int StartIndex )
{
    String *st = new String();

    if( StartIndex >= this->Len )
    {
        return *st;
    }

    st->Str = (char *) malloc( ( this->Len - StartIndex ) * sizeof( char ) );
    st->Len = ( this->Len - StartIndex );

    memcpy( st->Str , this->Str + StartIndex , this->Len );

    st->Str[ ( this->Len - StartIndex ) ] = '\0';

    return *st;
}

String & String::SubString( int StartIndex , int Length )
{
    String *st = new String();

    if( StartIndex + Length >= this->Len )
    {
        return *st;
    }

    st->Str = (char *) malloc( Length * sizeof( char ) );
    st->Len = Length;

    memcpy( st->Str , this->Str + StartIndex , Length );

    st->Str[ Length ] = '\0';

    return *st;

}

int String::IndexOf( const String & s )
{
    int i;

    for ( i = 0 ; i <= this->Len - s.Len ; i++ )
    {
        if ( !strncmp( this->Str + i , s.Str , s.Len ) )
        {
            return i;
        }
    }

    return -1;
}

char & String::operator [] ( int index )
{
    if( index < 0 || index > this -> Len )
    {
        printf( "Неверный индекс i = %d" , index );
        exit( 0 );
    }

    return this -> Str[ index ];
}

String & String::operator + ( const String & s )
{
    String * result = new String( this->Str );

    *result += (String &)s;

    return *result;
}

String & String::operator += ( const String & s )
{
    char    * st = this->Str;
    int         len = this->Len;

    this->Str = (char *) malloc( ( len + s.Len ) * sizeof( char ) );

    Len = strlen( st );
    memcpy( this->Str , st , this->Len );

    memcpy( this->Str + this->Len , s.Str , s.Len );
    Len += s.Len;

    Str[ Len ] = '\0';

    return *this;
}

String & String::operator = ( const String & s )
{
    this->Str = (char *) malloc( s.Len * sizeof( char ) );

    this->Str = s.Str;
    this->Len = s.Len;

    return *this;
}

String::~String()
{
    delete [] Str;
}

void main()
{
    String * Str1 , * Str2 , * Str3 , * Str4 , * Str5;

    Str1 = new String( "123456789" );
    Str2 = new String( "abcdefghi" );
    Str3 = new String();
    Str4 = new String();
    Str5 = new String( "abcdefghi" );

    printf( "Str1 = %s\nStr2 = %s\nStr3 = %s\nStr4 = %s\nStr5 = %s\n\n" , Str1->GetString() , Str2->GetString() , Str3->GetString() , Str4->GetString() , Str5->GetString() );

    *Str3 = (String &)(*Str2) + (String &)(*Str1);

    printf( "Str3 = Str2 + Str1 = \n\t\t\t\t\t\t%s\n" , Str3->GetString() );

    *Str1 += (String &)(*Str2);

    printf( "Str1 += Str2 = \n\t\t\t\t\t\t%s\n" , Str1->GetString() );

    *Str1 = Str1->SubString( 7 );

    printf( "Str1 = Subtring( 7 ) ( Str1 ) = \n\t\t\t\t\t\t%s\n" , Str1->GetString() );

    *Str4 = Str1->SubString( 2 , 4 );

    printf( "Str4 = Subtring( 2, 4 ) ( Str1 ) = \n\t\t\t\t\t\t%s\n" , Str4->GetString() );

    printf( "\nStr1 = %s\nStr2 = %s\nStr3 = %s\nStr4 = %s\nStr5 = %s\n\n" , Str1->GetString() , Str2->GetString() , Str3->GetString() , Str4->GetString() , Str5->GetString() );
    
    printf( "Str2 %s Str1\t" , ( Str2->operator > ( (String &)(* Str1) ) )  ? ">" : "<=" );
    printf( "Str3 %s Str2\t" , ( Str3->operator ==( (String &)(* Str2) ) ) ? "==" : "!=" );
    printf( "Str4 %s Str2\t" , ( Str4->operator !=( (String &)(* Str2) ) ) ? "!=" : "==" );
    printf( "Str5 %s Str2\t" , ( Str5->operator ==( (String &)(* Str2) ) ) ? "==" : "!=" );
    printf( "Str4 %s Str1\t" , ( Str4->operator < ( (String &)(* Str1) ) ) ? "<" : ">=" );
    printf( "Str1 %s Str4\n" , ( Str4->operator > ( (String &)(* Str4) ) ) ? ">" : "<=" );

    printf( "\n" );

    int pos;
    pos = Str1->IndexOf( *Str4 );

    if( pos > 0 )
    {
        printf( "Str4 IndexOf Str1 = %d\t\t" , pos );
    }
    else
    {
        printf( "Str4 IndexOf Str1 = not found\t\t" );
    }

    pos = Str3->IndexOf( *Str2 );

    if( pos > 0 )
    {
        printf( "Str3 IndexOf Str2 = %d\t" , pos );
    }
    else
    {
        printf( "Str3 IndexOf Str2 = not found\t" );
    }

    getch();
    exit(0);
}
 
PM ICQ   Вверх
MAKCim
Дата 30.5.2006, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Код

String & String::operator + ( const String & s )
{
    String * result = new String( this->Str );
    *result += (String &)s;
    return *result;
}


Код

String operator+(const String& str_a, const String& str_b)
{
    String str(str_a);
    str+=str_b;
    return str;
}

+ добавь конструктор копий
Код

String::String(const String& obj)
{
    int size=obj.GetLength();
    Str=new char [size];
    Len=size;
    for (int i=0; i<size; ++i) *(Str+i)=*(obj.Str+i);
}

а то тут будет ошибка
Код

void F(String str) {}

int main()
{
    String str("Test");
    F(str)
    return 0;
}

Цитата

Код

String::String( char * s )
{
    this->Str = (char *) calloc( strlen( s ) , sizeof( char ) );   // Можно new выделять
    this->Str = ( char * ) s;        // Зачем приведение?? + утечка памяти + возможно двойное удаление, нужно   //                      strncpy(this->Str,s,strlen(s));
    this->Len = this -> GetLength(); 
}


Цитата

Код

String::String( char ch )
{
    this->Str = (char *) malloc( sizeof( char ) );
    this->Str = ( char * )ch;     // Берем адрес объекта в стеке (после отработки конструктора Str будет ссылаться)
    this->Len = 1;                     // на невалидный объект + утечка памяти
}


Цитата

Код

int String::GetLength( void )
{
    return strlen( this -> Str ); // Крайне неэффективно, лучше один раз вычислить вначале и сохранить в Len
}



Добавлено @ 09:08 
Цитата

Код

String & String::operator = ( const String & s )
{
    this->Str = (char *) malloc( s.Len * sizeof( char ) );
    this->Str = s.Str;          // Опять утечка памяти + двойное удаление
    this->Len = s.Len;
    return *this;
}



Mal Hack
если есть
Код

char* str;

и он указывает на строку
то при
Код

char* a=str;

и a и str указывают на одну область памяти
в деструкторе String эта область освобождается, но освобождается в 2-ух объектах сразу!!, что приведет к ошибке 

Это сообщение отредактировал(а) MAKCim - 30.5.2006, 09:03


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Mal Hack
Дата 30.5.2006, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 2
Всего: 261



Цитата(MAKCim @  30.5.2006,  09:02 Найти цитируемый пост)
в деструкторе String эта область освобождается, но освобождается в 2-ух объектах сразу!!, что приведет к ошибке 

Это вроде бы обработали.
Задача - учебная. Тут все проще надо делать. 
PM ICQ   Вверх
MAKCim
Дата 30.5.2006, 12:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Тут все проще надо делать.

я же не предлягаю ее усложнить  smile 
просто тут не совсем все правильно 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Mal Hack
Дата 30.5.2006, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


Профиль
Группа: Участник Клуба
Сообщений: 9926
Регистрация: 15.2.2004

Репутация: 2
Всего: 261



Не спорю. Во внимание все приму. 
PM ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1253 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.