不使用原生的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;
}
}