在c++中创建自定义C类型字符串类

Creating a custom C type string class in C++

本文关键字:类型 字符串 自定义 c++ 创建      更新时间:2023-10-16

我有一个分配,我需要在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;
}

总结:

  • i在点行
  • 中重新初始化
  • strSize未初始化(天知道是什么),在同一行;strSize = strlen(str);
  • 字符串终止符错误
  • 就像那个男人说的那样,这里有点乱

    int i=0;
    while (str[i] != '') { // as Seth pointed out it's ''
        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] != '') 
       ++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] != '') 
       ++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;
    }

你的脚本太乱了。

你同时用i表示两种不同的东西。您还可以为str中的每个字符将str的整个内容复制到strPtr中一次。

基本上,你必须决定,你是否要使用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] != '') 
       ++i;
  strSize = i;
  strPtr = new char [i+1];
  for (i=0; i < strSize;++i)
        strPtr[i] = str[i];
} 

为什么两个循环一个在另一个里面?你想得太辛苦了,把字符从一个字符串复制到另一个字符串,你只需要一个循环。下面是一些代码

//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] = '';
}

更简单!