Создание собственного строкового класса типа C в C ++ - PullRequest
1 голос
/ 25 августа 2011

У меня есть задание, которое мне нужно, чтобы создать собственный строковый класс типа C в C ++.У меня проблемы с тем, чтобы заставить это работать.В настоящее время мой код вылетает с ошибкой во время выполнения в самом начале.Я также знаю, что многие из моих функций неверны, но я хочу отсортировать функции-члены, прежде чем продолжить и исправить другие функции.Имейте в виду, что все прототипы функций были переданы нам, и я не могу их изменить.Мне нужно написать «кишки», так сказать.

Что не так с моим конструктором для начала?

#include <iostream>
#include "tstr.h"
using namespace std;

//Default constructor to initialize the string to null
TStr::TStr() {
    strPtr = 0;
    strSize = 0;
}  
//constructor; conversion from the char string
TStr::TStr(const char *str) {
    int i=0;
    while (str[i] != '/0') {
        strPtr = new char [strlen(str)+1];
        for (i=0; i <strSize;++i) {
            strPtr[i] = str[i];
        }
        ++i;
    }
    strSize = i;
} 
//Copy constructor
TStr::TStr(const TStr&) {
}
//Destructor
TStr::~TStr() {
    if (strPtr) {
        delete[] strPtr;
    }
}

//subscript operators-checks for range
char& TStr::operator [] (int i) {
    assert (i >= 0 && i < strSize);
    return strPtr[i];
}
const char& TStr::operator [] (int i) const {
    assert (i >= 0 && i < strSize);
    return strPtr[i];
}

//overload the concatenation oprerator
TStr TStr::operator += (const TStr& str) {
    //this->strPtr += str.strPtr;
    //this->strSize += str.strSize;
    return *this;
}
//overload the assignment operator
const TStr& TStr::operator = (const TStr& str) {
    if (this != &str) {
        delete[] strPtr;
        strPtr = new char[strSize = str.strSize];
        assert(strPtr);
        for (int i=0; i<strSize; ++i) {
            strPtr[i] = str.strPtr[i];
        }
    }
    return *this;
}

//overload two relational operators as member functions
bool TStr::operator == (const TStr& str) const {
    return (strPtr == str.strPtr && strSize == str.strSize);
}
bool TStr::operator < (const TStr& str) const {
    return (strPtr < str.strPtr && strSize < str.strSize);
}
//the length of the string
int TStr::size() {
    return strSize;
}

Спасибо за любые ответы / помощь!:)

РЕДАКТИРОВАТЬ 1: Хорошо, конструктор теперь работает, но я все еще получаю ошибку времени выполнения, и я на 90% уверен, что это связано с моим перегруженным оператором + =.Это выглядит хорошо, хотя и компилируется хорошо.Что мне не хватает?

(Примечание: в приведенный выше код были внесены только небольшие изменения, но дайте мне знать, если хотите увидеть весь лот.)

//overload the concatenation oprerator
TStr TStr::operator += (const TStr& str) {
    for(int i = 0; i < strSize; ++i) {
        strPtr[i] += str.strPtr[i];
    }
    return *this;
}

РЕДАКТИРОВАТЬ 2: Хорошо, это то, что яесть сейчас.Компилируется нормально, но на самом деле не добавляет две строки вместе с + =, как должно.У кого-нибудь есть идеи?

//overload the concatenation oprerator
TStr TStr::operator += (const TStr& str) {
    char *buffer = new char[strSize + str.strSize + 1];
    strcpy(buffer, strPtr);
    strcat(buffer, str.strPtr);
    delete [] strPtr;
    strPtr = buffer;
    return *this;
}

//overload the assignment operator
const TStr& TStr::operator = (const TStr& str) {
    if (this != &str) {
        delete[] strPtr;
        strPtr = new char[strSize = str.strSize];
        assert(strPtr);
        for (int i=0; i<strSize; ++i) {
            strPtr[i] = str.strPtr[i];
        }
    }
    return *this;
}

Ответы [ 3 ]

3 голосов
/ 25 августа 2011

Подводя итог:

  • я повторно инициализирован в указанной строке
  • strSize используется неинициализированным (Бог знает, что там) в той же строке, что и выше;должно быть strSize = strlen (str);
  • неправильный характер терминатора строки
  • , поскольку человек говорил, что это беспорядок

    int i=0;
    while (str[i] != '\0') { // as Seth pointed out it's '\0'
        strPtr = new char [strlen(str)+1];
        for (i=0; i <strSize;++i) { // i is reinitialized here !!!
            strPtr[i] = str[i];
        }
        ++i;
    }
    strSize = i;
    

Чтобы быть более конструктивным:

// as James perfectly illustrated
TStr::TStr(const char *str) 
{
  int i = 0;
  while (str[i] != '\0') 
       ++i;
  strSize = i;
  strPtr = new char [i+1];

  while (*strPtr++ = *str++); // with a bit of k&R
} 

//overload the concatenation oprerator
TStr TStr::operator += (const TStr& str) {
    for(int i = 0; i < strSize; ++i) {
        strPtr[i] += str.strPtr[i];
    }
    return *this;
}

Проблемы:

  • вы хотите объединить строки, что означает, что вам нужно больше места для хранения обеих строк, то есть вам нужноперераспределить массив символов, и вы не сделаете этого
  • вы не обновляете размер вашей строки, теперь он больше, не так ли?
  • strPtr [i] += str.strPtr [i]; здесь вы действительно добавляете целые числа, хранящиеся в 8 битах

Решение (я абсолютно уверен, что это можно улучшить, но вам стоит начать):

//overload the concatenation oprerator
TStr TStr::operator += (const TStr& str) {
    unsigned int i = 0;
    while (str.strPtr[i] != '\0') 
       ++i;
    // allocate the new buffer
    char* newStr = new char[i + strSize + 1];
    // copy the old string
    unsigned int j = 0;
    for (; j < strSize; ++j) 
    {
        newStr[j] = strPtr[j];
    }
    // update the size
    strSize += i;
    // release the old buffer
    delete[] strPtr;
    // finally concatenate
    char* copyPtr = newStr + j;
    while(*copyPtr++ = *(str.strPtr)++);
    // and swap the pointers
    strPtr = newStr;     
    return *this;
    }
2 голосов
/ 25 августа 2011

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

//constructor; conversion from the char string
TStr::TStr(const char *str) {
    strSize = strlen(str);
    strPtr = new char [strSize+1];
    for (int i=0; i <strSize; ++i) {
        strPtr[i] = str[i];
    }
    strPtr[strSize] = '\0';
}

Намного проще!

2 голосов
/ 25 августа 2011

Ваш ctor в значительной степени беспорядок.

Вы используете i для двух разных вещей - одновременно. Вы также копируете все содержимое str в strPtr один раз для каждого символа в str.

По сути, вы должны решить, собираетесь ли вы использовать библиотеку времени выполнения C или нет?

Используя его:

TStr::TStr(const char *str) 
{
  strSize = strlen(str);
  strPtr = new char [strSize+1];
  strcpy(strPtr, str);
}

не использует его:

TStr::TStr(const char *str) 
{
  int i = 0;
  while (str[i] != '\0') 
       ++i;
  strSize = i;
  strPtr = new char [i+1];
  for (i=0; i < strSize;++i)
        strPtr[i] = str[i];
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...