string类的讲解
C++学习过程就是一次看不懂,几次懵懵懂懂,最后写得多了,才能看点门道的。着过程前期还是比较难受的,后面有点顿悟的感觉,也是不错。
C++的字符串与C有很大的不同,首先C中是char*类型,而在C++中变成了string类型
//C
char* str = "caizi";
//C++
string str = "caizi";
string str("caizi2");
在C中对字符串的操作就是对str指针操作,增删改查都是在内存上进行操作的,非常高的自由度,但就是容易引起内存上的错误;
在C++上。string类提供了很多内建函数方法,用户无需在底层上纠结,其有一些优点,例如,支持重载连接运算符“+”,比较,输入输出,以及一些内建的查找方法;迭代器使得数据与操作分离,对程序的移植,接口扩展维护很有优势;
//C
char *str = "caizi";
//这是一个const类型,无法写操作
char str[] = "caizi";
//定义成数组,才能,但是不能越界,否则会导致内存问题
/*
字符串的操作
printf("%s",ptr); %s格式化输出从ptr地址开始一个字节一个字节读取数据,直至遇到结尾符
strlen(ptr) ;返回字符串的长度(一个字符串包含字符的个数)
strcpy(dst,src); 把从src开始的数据拷贝到dst中,dst的大小一定要比src的大
strcmp(lstr,rstr); 判断两个字符串是否相等
strncpy(dst,src,size); 从src拷贝size个数据到dst
strncmp(lstr,rstr,size); 比较两个字符串的前size个字节
strdup() ;复制一个字符串对象,自动调用malloc动态申请内存空间,用完后需要free
*/
对于C++,就给几个实例,看完也差不多了
查找给定字符串并相应子串替换为另一个给定字符串
int str_replace(string &str, const string &src, const string &dest)
{
int counter = 0;
string::size_type pos = 0;
while ((pos = str.find(src, pos)) != string::npos) {
str.replace(pos, src.size(), dest);
++counter;
pos += dest.size();
}
return counter;
}
从给定字符串中删除一给定字符串
int str_erase(string &str, const string src)
{
int counter = 0;
string::size_type pos = 0;
while ((pos = str.find(src, pos)) != string::npos) {
str.erase(pos, src.size());
++counter;
}
return counter;
}
给定一字符串和一字符集,从字符串剔除字符集中的任意字符
int str_wash(string &str, const string src)
{
int counter = 0;
string::size_type pos = 0;
while ((pos = str.find_first_of(src, pos)) != string::npos) {
str.erase(pos, 1);
++counter;
}
return counter;
}
string实现
#include<iostream>
#include<string.h>
using namespace std;
class String{ //String的定义
public:
String(const char *str=NULL); //构造
String(const String& Str); //复制构造
String& operator = (const String& S); //运算符重载
PrintString();
~String();
char *m_data;
};
//需要注意:1、判断参数str是否为NULL;2、赋值前需要给成员变量m_data申请内存
String::String(const char *str){ //判断初始化构造函数的字符串是否为空
if(str == NULL){
m_data = new char[1];
m_data[0] = '\0';
}
else{
m_data = new char[strlen(str)+1];
strcpy(this->m_data,str);
}
}
String::String(const String& Str){ //复制构造函数,无需判断
m_data = new char[strlen(Str.m_data)+1];
strcpy(this->m_data,Str.m_data);
}
String& String::operator = (const String& S){ //运算符重载,先判断两串是否相等
//String A
//String B = A
if(S.m_data == this->m_data){ //若相等则直接返回this指针
return *this;
}
//删除新开是方式内存溢出
else{ //若不等则需要先删除原先开辟的内存,再重新分配
delete []m_data; //这是为了防止被赋值的串的大小与赋值串的大小不同
m_data = new char[strlen(S.m_data)+1]; //而导致拷贝串时发生错误
strcpy(this->m_data,S.m_data);
}
}
String::~String(){ //释放内存时需要将原指针指向空,避免成为野指针
delete []m_data;
m_data = NULL;
}
String::PrintString(){
cout<<this->m_data<<endl;
}
int main(){
String S("dafagag");
S.PrintString();
String S2;
S2 = S;
S2.PrintString();
return 0;
}
总结
C与C++字符串各有优点,但总的来看C++用起来更方便(内存开销大),C的操作内存自由度更高,;