C++快速入门--8--构造一个字符串类

不使用原生的string类,如何写入自定义长度字符串

当我们读取一个字符串的时候,通常是定义一个大数组来存放这些内容,但是,有时候,我们不知道内容有多大的时候,这时候如何定义数组的大小呢?一种做法是,我们定义一个大数组,然后通过realloc来减小数组的大小,并能减小内存的消耗。还有一种做法是,边扩大数组,边存放内容,在扩大数组的时候,将数据转存到另外一个数组。

//String类中含char * s;指针
istream & operator>>(istream & in,String & str){
    int i = 1;
    char * s;
    if(str.s){
        str.s = delete [] str.s;
    }
    str.s = new char[i+1];//至少分配两个字节,一个用来存'\0'
    while((str.s[i++-1])!= '\n'){
        s = new char[i+1];
        str.s[i-1] = '\0';
        strcpy_s(s,i,str.s);
        delete [] str.s;
        str.s = new char[i + 1];
        strcpy_s(str.s,i,s);
        delete [] s;
    }
    str.s[i-1] = '\0';
    return in;
}   

核心思想是如果将自身扩大,这里是用另外一个数组临时存放当前数据, 然后再将自身扩大之后,再将数据存回来。

String类的实现

实现功能:

  • String s = “asd”;
  • String s1 = “asd”; String s2; s2 = s1;
  • String s;
  • s1 = “123”
  • s1 == s2
  • “123” == s1
  • !=的情况
    <> 的情况 可以直接与字符串比较,也可以与String类比较
    <<写出 和>>写入
    []取值和赋值

//String.h
#include "iostream"
using namespace std;
#pragma once
class String
{
    friend ostream & operator<<(ostream & out, const String & str);
    friend istream & operator>>(istream & in, String & str);
    friend bool operator==(const char * p, const String & str);
    friend bool operator<(const char * p, const String & str);
    friend bool operator>(const char * p, const String & str);
private:
    char * s;
    int length;
public:
    String(int length = 0);
    String(const String & str);
    String(const char *p);
    ~String();
public:
    bool operator == (const String & str) const;
    bool operator == (const char * p) const;
    bool operator != (const String & str) const;
    bool operator != (const char * p) const;
public:
    String & operator=(const String & str);
    String & operator=(const char * p);
    char & operator[](int index);
public:
    bool operator<(const char *p) const;
    bool operator<(const String & str) const;
    bool operator>(const char *p) const;
    bool operator>(const String & str) const;

public:
    char * getS() { //可修改
        return this->s;
    }
    const char * getStr(){  //不可修改
        return this->s;
    }
    int Length() {
        return this->length;
    }
};

/*****************************************************************/

//String.cpp
#include "String.h"
#include "cstring"
#include "iostream"
using namespace std;

/*
    构造一个字符串,返回一个空串
*/
String::String(int length)
{
    this->length = length;
    if(length == 0){
        this->s = NULL;
    }else{
        this->s = new char[this->length + 1];
        memset(this->s,0,this->length + 1);
    }
}
/*
    通过一个字符串常量构造一个String对象,支持String s = "123";的写法
*/
String::String(const char * p) {
    if (p == NULL) {
        this->length = 0;
        this->s = NULL;
    }
    else {
        this->length = strlen(p);
        this->s = new char[this->length + 1];
        strcpy_s(this->s, this->length + 1, p);
    }
}
/*
    拷贝构造函数,传递一个String对象之间构造,支持String s1 = s2;
*/
String::String(const String & str) {
    this->length = str.length;
    this->s = new char[this->length +1];
    strcpy_s(this->s,this->length + 1, str.s);
}
/*
    =重载,可以通过String s1; s1=s2;赋值
*/
String & String::operator=(const String & str) {
    if (this->s) {
        delete[] s;
    }
    this->length = str.length;
    if (str == NULL) {
        this->s = NULL;
    }else{
        this->s = new char[this->length + 1];
        strcpy_s(this->s, this->length + 1, str.s);
    }
    return *this;
}

/*
    =重载,可以通过String s1; s1 = "200"; 赋值
*/
String & String::operator=(const char * s) {
    if (s == NULL) {
        this->length = 0;
        this->s = NULL;
    }
    else {
        this->length = strlen(s);
        this->s = new char[this->length + 1];
        strcpy_s(this->s, this->length + 1, s);
    };
    return *this;
}

/*
    []重载,可以通过String s1,s1[0] = 'a';直接赋值
*/ 
char & String::operator[](int index) {
    return this->s[index];
}

/*
    ==重载,判断 s1 == s2
*/
bool String::operator == (const String & str) const {
    if (this->length == str.length && str.s == NULL && this->s == NULL) return true;
    if (this->length == str.length && !strcmp(this->s, str.s)) return true;
    return false;
}

/*
    ==重载,判断 s1 == "200";
*/
bool String::operator == (const char * s) const{
    if (s == NULL && this->s == NULL) return true;
    if (this->length == strlen(s) && !strcmp(this -> s, s)) return true;
    return false;
}
/*
    !=重载
*/
bool String::operator!=(const String & str) const {
    return !(*this == str);
}
/*
    !=重载
*/
bool String::operator!=(const char * s)const {
    return !(*this == s);
}

bool String::operator<(const char *p) const {
    if (p != NULL && this->s != NULL)
        if (strcmp(this->s, p) < 0) return true;
    return false;
}

bool String::operator<(const String & str) const {
    if (*this != NULL && str != NULL && strcmp(this->s, str.s) < 0)  return true;
    return false;
}

bool String::operator>(const char * p)const {
    if (p != NULL && this->s != NULL && strcmp(this->s, p) > 0) return true;
    return false;
}

bool String::operator>(const String & str) const{
    if (str.s != NULL && this->s != NULL && strcmp(this->s, str.s) > 0) return true;
    return false;
}

ostream & operator<<(ostream & out, const String & str) {
    out << str.s;
    return out;
}
/*
    通过动态分配内存,实现不定长字符串的写入
*/
istream & operator>>(istream & in, String & str) {
    char * s;
    int i = 1;
    if (str.s) {
        delete[] str.s;
    }
    str.s = new char[i + 1];
    while ((str.s[i - 1] = getchar()) != '\n') {
        i++;
        s = new char[i + 1];
        str.s[i - 1] = '\0';
        strcpy_s(s,i ,str.s);
        delete[] str.s;
        str.s = new char[i + 1];
        strcpy_s(str.s, i,s);
        delete[] s;
    }
    str[i - 1] = '\0';
    str.length = i;
    return  in;
}



bool operator==(const char * p, const String & str) {
    return str == p;
}

bool operator<(const char * p, const String & str) {
    return str > p;
}

bool operator>(const char * p, const String & str) {
    return str < p;
}

String::~String()
{
    this->length = 0;
    if (this->s) {
        delete[] this->s;
        this->s = NULL;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值