第十八章 字符串

第十八章 字符串

1.  char型字符串

char man[5]={“jack”};等价于char man[]={“jack”};

等价于man[5]={'j','a','c','k',''};

请不要小看这个代表字符串结束的标志‘’,‘’是一个空字符标志,它的ASCII码为0,C++有好多处理字符串的函数,它们都以‘’为结束标志,也就是以空字符为结束标志,比如说cin和cout,它们也是以空字符为结束标志,假如它们在碰到空字符后将会停止输入或输出。

字符串常量系统会自动加上 。字符常量系统不会自动加上

char man[]={'a',32,'b',''};等价于char man[]={'a',32,'b',0};

32为ASCII码不能加单引号,否则不能代表空格符

0代表空字符

若不加 man就不能代表字符串。只能代表数组man[]输出就会越界就会打出乱码。

空字符:ASCII为:0, 其字符标识符为:’’;为字符串结束标识符

空格符:ASCII为:32,其字符标识符为:’  ’;

cin>>cha;遇到空格符就会结束;

cin.get(cha,n);遇到 才结束。因为它会在末尾自动加上 ,实际保存.字符只有n-1;

字符数组必须要加一个字符串结束标志’’ 不然不知道结束;

char man[]={‘a’,’b’,’c’};出现乱码

char man[]={“abc”};不会出现乱码,自动加上;

2.  string型字符串

char型是C语言风格的字符串 是用数组来保存字符串的

string型是C++风格的字符串 要添加<string>类,所以定义的变量时是string类 的对象。

2.1  string型字符串的赋值

注意:赋值要先清0再赋值(strcpy),替换不需要(strncpy)

char字符串有两种方法:①strcpy②每个元素一个一个的赋值,如a[0]=b[0];

 1 /*
 2 strcpy和memcpy主要有以下3方面的区别。
 3 1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
 4 2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符""才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
 5 3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
 6 */
 7 
 8 //①使用strcpy
 9 //#include <iostream>
10 //using namespace std;
11 //int main()
12 //{
13 //    char a[20]="My name is";
14 //    char b[]=" Jack.";
15 //    std::cout<<strcpy(a,b);// string copy 先清除a中的所有字符,再将b中的所有字符(包括空字符)复制到a中
16 //    return 0;
17 //}
18 
19 //②常规赋值
20 #include <iostream>
21 #include"string"
22 using namespace std;
23 int main()
24 {
25     char a[20]="My name is";
26     char b[]=" Jack.";
27     memset(a,0,sizeof(a));//一般和extern void *memcpy(void *dest, void *src, unsigned int count); 配套使用
28     for(int i=0; i< strlen(b); i++)
29     {
30         a[i]=b[i];
31     }
32     cout<< a << endl;
33     return 0;
34 }

而string型字符串可以直接赋值

 1 //string型字符串对象的赋值实例的程序代码如下:
 2 /*
 3 #include <iostream>
 4 #include <string>
 5 using namespace std;
 6 int main()
 7 {
 8    string str1="what's your name";
 9    string str2="my name is Jack";
10    str1=str2;
11    cout<<str1<<endl;
12    cout<<str2<<endl;
13    return 0;
14 }
15 */
16 
17 //另外,我们也可以调用string类的赋值函数assign,该函数可以取第2个字符串的任意字符赋给第1个字符串,如:
18 #include <iostream>
19 #include <string>
20 using namespace std;
21 int main()
22 {
23    string str1=" gh ";
24    string str2 = " abcdef ";
25    str1.assign( str2, 3, 1 );  
26    cout << str1 << endl;
27    return 0;
28 }

2.2  string型字符串的合并

 1 //要避免这个错误,要将ch1的长度修改为能容纳两个数组的长度。如:
 2 
 3 //#include <iostream>
 4 //using namespace std;
 5 //int main()
 6 //{
 7 //  char ch1[36]="what's your name.";//必须要能容纳两个字符数组的长度
 8 //  char ch2[]=" my name is Jack";
 9 //  //strcat(ch1,ch2);        //string catenate  ①
10 //  //cout<<ch1<<endl;
11 //  //cout<<ch2<<endl;
12 //  strncat(ch1,ch2,8);        //将ch2的头8个字符连接到ch1后;  ②
13 //  cout<<ch1<<endl;
14 //  return 0;
15 //}
16 
17 /*C++ string append()添加文本
18 使用append()添加文本常用方法:
19 直接添加另一个完整的字符串:
20 ①如str1.append(str2);
21 添加另一个字符串的某一段子串:
22 ②如str1.append(str2, 11, 7);
23 添加几个相同的字符:
24 ③如str1.append(5, '.');
25 注意,个数在前字符在后.上面的代码意思为在str1后面添加5个"."  */
26 
27 //string型字符串的合并的实例的程序代码如下:
28 
29 #include <iostream>
30 #include <string>
31 using namespace std;
32 int main()
33 {
34    string str1;
35    cout<<"str1:"<<str1.size()<<endl;
36    str1 ="what's your name. ";
37    cout<<"str1:"<<str1.size()<<endl;
38    string str2="my name is Jack";
39    cout<<"str2:"<<str2.size()<<endl;
40    //str1=str1+str2;            //
41    str1.append(str2,11,4);        //
42 
43    cout<<str1<<endl;
44    cout<<str2<<endl;
45    cout<<"str1:"<<str1.size()<<endl;
46    cout<<"str2:"<<str2. length()<<endl;
47    return 0;
48 }

2.3  string型字符串的替换  

注意:赋值要先清0再赋值(strcpy),替换不需要(strncpy)

 1 //char型字符串的替换。程序代码如下:
 2 
 3 //#include <iostream>
 4 //using namespace std;
 5 //int main()
 6 //{
 7 //   char ch1[10] = "ghadfadf";
 8 //   char ch2[]= "abcdef";
 9 //   strncpy(ch1,ch2,3);    //不需要将ch1清零//   cout<<ch1<<endl;
10 //   return 0;
11 //}
12 
13 
14 
15 //string类成员函数 replace的第3种重载方式程序代码如下:
16 //#include <iostream>
17 //#include <string>
18 //using namespace std;
19 //int main()
20 //{
21 //   string str1 = "gh";
22 //   string str2 = "abcdef";
23 //   str1.replace(0,1,str2,4,2);
24 //   cout<<str1<<endl;    // 输出结果为: efh
25 //   return 0;
26 //}
27 
28 ////replace重载函数支持char型字符串,如:
29 
30 //#include <iostream>
31 //#include <string>
32 //using namespace std;
33 //int main()
34 //{
35 //  string str1 = "gh";
36 //  char str2[] = "abcdef";
37 //  str1.replace(0,1,str2,4,2);
38 //  cout<<str1<<endl;    // 输出结果为: efh
39 //  return 0;
40 //}
41 
42 
43 
44 ////另外,replace重载函数也支持char型字符,也就是第5种重载格式,如:
45 #include <iostream>
46 #include <string>
47 using namespace std;
48 int main()
49 {
50    string str1 = "gh";
51    char ch1='1';
52    str1.replace(0,2,2,ch1);
53    cout << str1 << " " << ch1 << endl;
54    return 0;
55 }

2.4  string型字符串的复制(其实和替换一样的)

 1 //char型字符串的复制。程序代码如下:
 2 
 3 //#include <iostream>
 4 //using namespace std;
 5 //int main(void)
 6 //{
 7 //   char ch1[15] = "abcdefghijklmn";
 8 //   char ch2[] = "1234567890";
 9 //   cout<<"源字符串"<<ch1<<endl;
10 //   memmove(ch1, ch2, 9);
11 //   cout<<"拷贝后:" <<ch1<<endl;
12 //   return 0;
13 //}
14 
15 
16 //string型字符串的复制,程序代码如下:
17 
18 #include <iostream>
19 #include <string>
20 using namespace std;
21 int main(void)
22 {
23    string str = "abcd";
24    char ch []= "1234";
25    int n;
26    cout<<"源字符串"<<ch<<endl;
27    n=str.copy(ch, 4,0);
28    cout<<"拷贝了"<<n<<"字符"<<endl;
29    cout<<"拷贝后:" <<ch<<endl;
30    return 0;
31 }

2.5  string型字符串的插入

 1 //string类insert成员函数的使用。程序代码如下:
 2 #include <iostream>
 3 #include <string>
 4 using namespace std;
 5 int main()
 6 {
 7    string str="12789";
 8    string str1="3456";
 9    str.insert(2,str1,0,3);
10    cout<<str<<endl;
11    return 0;
12 }

2.6  string型字符串的删除

 1 //string类erase成员函数的使用。程序代码如下:
 2 #include <iostream>
 3 #include <string>
 4 using namespace std;
 5 int main()
 6 {
 7    string s("give me");
 8    cout << "原始字符串为:" << s<< endl; // give me
 9    s.erase( 2, 2 );
10    cout << "现在字符串为:" << s << endl;// gi me
11    s.erase( 2 );
12    cout << "现在字符串为:" << s << endl;// gi
13    s.erase();
14    cout << "现在字符串为:" << s << endl;// 
15    return 0;
16 }

2.7  string型字符串的查找

f=str1.find(‘w’,0);//在str1中从零开始查找,

//如何没有找到f的值等于string::npos(各编译器值不同,vc为-1)

f=str1.rfind(‘w’,10);//reverse find

f=str1.find_first _of(‘w’,0);

f=str1.find_first_not_of(‘w’,0);

f=str1.find_last _of(‘w’);

f=str1.find_last _not_of(‘w’);

 1 //查找char型字符串。程序代码如下:
 2 //#include <iostream>
 3 //using namespace std;
 4 //int main(void)
 5 //{
 6 //   char ch1[15];
 7 //   char *p, c = 'w';
 8 //   strcpy(ch1, "hello world");
 9 //   p = strchr(ch1, c);  //extern char *strchr(const char *s,char c);查找字符串s中首次出现字符c的位置//p返回的是一个地址,如果没有找到返回NULL
10 //   if (p)
11 //   cout<<"字符"<<c<<"位于第"<<p-ch1<<endl;//输出:字符w位于第6//☆P-ch1  p偏移了ch1几位,是个int型数值
12 //   else
13 //   cout<<"没有找到";
14 //   return 0;
15 //}
16 
17 
18 
19 //查找string型字符串。程序代码如下:
20 #include <iostream>
21 #include <string>
22 using namespace std;
23 int main()
24 {
25    string str1( "hello world" );
26    int f = str1.find( "w",0);
27    if( f!= string::npos )//npos是一个常数,用来表示不存在的位置,类型一般是std::container_type::size_type 
28                         //许多容器都提供这个东西。取值由实现决定,一般是-1,这样做,就不会存在移植的问题了。npos表示string的结束位子,
29    cout << "在第 " << f<<"个字符" << endl;
30    else
31    cout << "没有找到" << endl;
32    return 0;
33 }

2.8  string型字符串的比较

比较(string重载了==运算符)

①char型字符串的比较:strcmp(ch1,ch2);

②string型字符串的比较:

str1.compare(str2);

str1.compare(0,2,str2);

str1.compare(0,2,str2,0,1);

注意str2可以换成ch

char ch=“pig”;if(ch==“pig”);//不可以比较(ch为数组)(只能单个比较或者用strcmp)

 1 #include<iostream>
 2 using namespace std;
 3 void main( )
 4 {
 5     char a[]="ABC";
 6     char b[]="ABd";
 7     if(strcmp(a,b)==1)    // string compare
 8         cout << "a大" << endl;
 9     else if(strcmp(a,b)==0)    
10         cout << "a等于b" << endl;
11     else if(strcmp(a,b)==-1)    
12         cout << "b大" << endl;
13 }

string str=“pig”;if(str==“pig”);//可以比较(str为对象)//“pig” 未命名字符串是常量是储存在文字常量区,只能读取不能更改

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 int main()
 5 {
 6    string s1="155";
 7    string s2="52";
 8    char c[]="12";
 9    int i,j,k,l,m,n;
10    i=s1.compare(s2);            //将s2与s1比较,返回0为相等,返回1为s1大于s2,    返回-1为s1小于s2
11    j=s2.compare(c);            //将char型字符串c与s2比较
12    k=s1.compare(0,2,s2);        //取s1前两个字符与s1进行比较,参数2表示取的s1的字符长度
13    l=s1.compare(1,1,s2,0,1);    //取s1[1]与s2[0]进行比较,第2个参数和第5个参数分别表示取的s1和s2的字符长度
14    m=s1.compare(1,1,c,0,1);    //取s1[1]与c[0]进行比较,第2个参数和第5个参数分别表示取的s1和c的字符长度
15    n=s1.compare(1,1,c,1);        //取s1[1]与c[0]进行比较,第2个参数表示取的s1的字符长度
16    cout<<s1<<":"<<s2<<"="<<i<<endl;     //依次输出各次比较结果
17    cout<<s2<<":"<<c<<"="<<j<<endl;
18    cout<<s1[0]<<s1[1]<<":"<<s2<<"="<<k<<endl;
19    cout<<s1[1]<<":"<<s2[0]<<"="<<l<<endl;
20    cout<<s1[1]<<":"<<c[0]<<"="<<m<<endl;
21    cout<<s1[1]<<":"<<c[0]<<"="<<n<<endl;
22    return 0;
23 } 

2.9  判断string型字符串是否为空

str.empty();//若str为空,返回真

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 int main()
 5 {
 6    string str="";
 7    if(str.empty())
 8    cout<<"字符串为空!";
 9    else
10    cout<<str;
11    return 0;
12 }

3.1   swap 交换两个字符串的内容

swab(ch1,ch2,strlen(ch1));

str1.swap( str2 );

 1 //char
 2 //#include <iostream>
 3 //using namespace std;
 4 //char ch1[15] = "ofru";
 5 //char ch2[15]="";
 6 //int main(void)
 7 //{
 8 //   swab(ch1, ch2, strlen(ch1));//用法:void swab(char *from, char *to, int nbytes);功 能: 交换相临的两个字节
 9 //   cout<<ch1<<endl;
10 //   cout<<ch2<<endl;
11 //   return 0;
12 //}
13 
14 
15 
16 //string型字符串的交换。程序代码如下:
17 #include <iostream>
18 #include <string>
19 using namespace std;
20 int main()
21 {
22    string str="give me";
23    string str1="a cup";
24    str.swap(str1);//交换两个字符串
25    cout<<str<<endl;
26    cout<<str1<<endl;
27    return 0;
28 }

3.2  将string型字符串转为char型字符串

atoi(S3.c_str())c_str是将str的对象转化成char的数组
 1 #include<iostream>
 2 #include <string>
 3 #include <sstream>
 4 
 5 using namespace std;
 6 void main()
 7 {
 8 // 将 int 转成 string
 9     //方法一 sprintf
10     int N1 = 123;
11     char C1[10];
12     string S1;
13     sprintf(C1,"%d",N1);    //只能将int型转换成char型*******************************①
14     //sprintf(S1,"%d",A1);  //不能直接将int型转成string型
15     S1 = C1;            //将char型转换成string型********************************②
16     cout << N1 << " " << C1 << " " << S1 << endl;
17     
18     //方法二 #include <sstream>
19     stringstream Ss1;
20     int N2 = 123;
21     string S2;
22     Ss1<<N2;    //将n放入ss流中
23     Ss1>>S2;    //从ss流中提取放入str中
24     cout<< N2 << " " << S2 << endl;
25     
26 // string 转 int
27     //方法一 atoi(S3.c_str())
28     string S3 = "qwe";
29     int N3 = atoi(S3.c_str());//只适合将string型的整形转换成int型的整形。如str="123"转换成int=123 
30     cout<< S3 << " " << N3 << endl;
31     //方法二 #include <sstream>
32     stringstream Ss2;        //只适合将string型的整形转换成int型的整形。如str="123"转换成int=123
33     int N4;
34     string S4 = "qwe";
35     Ss2<<S4;    //将n放入ss流中
36     Ss2>>N4;    //从ss流中提取放入str中
37     cout<< S4 << " " << N4 << endl;
38 }

3.3  char型字符串与函数

①字符串数组要利用数组名和空字符

 1 int get(const char p[])
 2 {
 3     int count = 0;
 4     while(*p)  //地址
 5     {
 6         count++;
 7         p++;    
 8     }        
 9     return count;
10 }

②c语言三种不同字符串表达方式

1.”study”;//字符串常量,只有头地址,不能单个元素输出

2.char* p=”very well”;// 字符串常量,只有头地址不能单个元素输出

3.char ch[15]=”hello world”;//可以单个输出

4.char man[5]={'J','a','c','k',''};

3.4  函数如何返回字符串

 1 //返回一个字符串的地址。程序代码如下:
 2 #include <iostream>
 3 #include <string>
 4 using namespace std;
 5 char *get(char*str);
 6 int main()
 7 {
 8    char c[10];
 9    char *ch;
10    cout<<"请输入您的名字!";
11    cin>>c;
12    ch=get(c);
13    cout<<"您的名字是"<<ch<<endl;
14    delete []ch;
15    ch=get("Jack");
16    cout<<"您的名字是"<<ch<<endl;
17    delete []ch;
18    char *ch1="Mike";
19    ch=get(ch1);
20    cout<<"您的名字是"<<ch<<endl;
21    delete []ch;
22    return 0;
23 }
24 char *get(char*str)
25 {
26    char *p=new char[strlen(str)+1];//换成char *p=new char[sizeof(str)]=new char[4]; 就出错???
27    strcpy(p,str);
28    cout<<p;
29    return p;
30 }

4.  结构体

结构体与类唯一不同的是成员默认为公有。也正因为如此我们可以将结构体当成复杂的数据类型使用

 1 //#include <iostream>
 2 //using namespace std;
 3 //struct people
 4 //{
 5 //    double weight;
 6 //    double tall;
 7 //    int age;
 8 //    char *name;
 9 //    char *native;
10 //    bool sex;
11 //};
12 //void check(bool s){if(s==1)cout<<"男"<<endl;else cout<<"女"<<endl;}
13 //int main()
14 //{
15 //    people Jack=
16 //    {                    //注意:此处是{}***********************************①
17 //        180.5,
18 //        179.3,
19 //        34,
20 //        "Jack",
21 //        "济南",
22 //        1
23 //    };
24 //    cout<<Jack.name<<endl;
25 //    cout<<Jack.native<<endl;
26 //    cout<<Jack.tall<<endl;
27 //    cout<<Jack.weight<<endl;
28 //    cout<<Jack.age<<endl;
29 //    check(Jack.sex);
30 //    return 0;
31 //}
32 
33 
34 
35 //结构体与构造函数。程序代码如下:
36 #include <iostream>
37 #include <string>
38 using namespace std;
39 struct people
40 {
41    people(double t_weight,double t_tall,int t_age,string t_name, char *t_native,bool t_sex);
42    double weight;
43    double tall;
44    int age;
45    string name;
46    char *native;
47    bool sex;
48 };
49 people::people(double t_weight,double t_tall,int t_age,string t_name, char *t_native,bool t_sex)
50 {
51    weight = t_weight;
52    tall = t_tall;
53    age = t_age;
54    name = t_name;
55    native = t_native;
56    sex = t_sex;
57 };
58 void check(bool s){if(s==1)cout<<""<<endl;else cout<<""<<endl;}
59 
60 int main()
61 {
62    people Jack
63     (                //注意:此处是()*************************②
64       180.5,
65       179.3,
66       34,
67       "Jack",
68       "济南",
69       1
70    );
71    cout<<Jack.name<<endl;
72    cout<<Jack.native<<endl;
73    cout<<Jack.tall<<endl;
74    cout<<Jack.weight<<endl;
75    cout<<Jack.age<<endl;
76    check(Jack.sex);
77    return 0;
78 }

①直接单个赋值:Jack.weight=150;

②没有构造函数时的成员赋值:注意{};

③有了构造函数时的成员赋值:注意();

④结构体对象相互赋值:people Mick={12,34,34,54};people Jack={42,24,54,64};Mick=Jack;

19.结构体与函数

 1 #include <iostream>
 2 using namespace std;
 3 struct time
 4 {
 5     int hour;
 6     int minute;
 7 };
 8 const int perhour=60;
 9 time &sum(time t1,time t2);
10 void show(time t);
11 int main()
12 {
13     time one={8,15};
14     time two={6,55};
15     time *day=&sum(one,two);
16     cout<<"两天总计:";
17     show(*day);
18     time day2={9,35};
19     cout<<"三天总计:";
20     time *p1=&sum(*day,day2);
21     show(*p1);
22     delete day;
23     delete p1;
24     return 0;
25 }
26 
27 time &sum(time t1,time t2)
28 {
29     time *total=new time;
30     total->minute=(t1.minute+t2.minute)%perhour;
31     total->hour=t1.hour+t2.hour+(t1.minute+t2.minute)/perhour;
32     return *total;
33 }
34 
35 void show(time t)
36 {
37     cout<<t.hour<<":"<<t.minute<<endl;
38 }

20.结构体与string

21.string数组与函数

22.流的简介

 

23.重载输出运算符

由于每次调用都会返回s(即cout)所以cout<<a<<b;可以级联;

 1 //错误代码。程序代码如下:
 2 /*
 3 #include <iostream>
 4 using namespace std;
 5 class A 
 6 {
 7 public:
 8 A(int x,int y){rx=x;ry=y;}
 9 private:
10 int rx;
11 int ry;
12 };
13 
14 int main()
15 {
16 A a(3,4),b(5,6);
17 cout<<a<<b;    //不可以直接输出对象
18 return 0;
19 }
20 */
21 
22 //纠正代码 如下:
23 #include <iostream>
24 using namespace std;
25 class A 
26 {
27 public:
28     A(int x,int y){rx=x;ry=y;}
29 public:
30     int rx;    //公有的
31     int ry;    //
32 };
33 ostream & operator << (ostream & s,const A & c)//ostream没有公有的复制构造函数,所以只能按引用复制对象返回对象。
34 {
35     s<<c.rx;
36     s<<c.ry;
37     return s;
38 }
39 int main()
40 {
41     A a(3,4),b(5,6);
42     cout<<a<<b;
43     return 0;
44 } 

☆24.友元的方式重载输出运算符

<<在未遇到cout时是左移运算符。遇到之后是输出运算符。

 1 //友元的方式重载输出运算符。程序代码如下:
 2 #include <iostream>
 3 using namespace std;
 4 class A 
 5 {
 6 public:
 7     A(int x,int y){rx=x;ry=y;}
 8     friend ostream& operator<<(ostream &s,const A c)
 9     {
10         s<<c.rx;
11         s<<c.ry;
12         return s;
13     }
14 private:
15     int rx;    //私有的
16     int ry;
17 };
18 int main()
19 {
20     A a(3,4),b(5,6);
21     cout<<a<<b<<endl;
22     return 0;
23 }

25.重载自加运算符的执行次序

 1 #include <iostream>
 2 using namespace std;
 3 class A 
 4 {
 5 public:
 6     A(int x){rx=x;}
 7     int operator++(){cout<<"++i
";rx++;return rx;}
 8     int operator++(int){cout<<"i++
";int i=rx;rx++;return i;}
 9     friend ostream& operator<<(ostream &s,const A c)
10     {
11         s<<c.rx;
12         return s;
13     }
14 
15 private:
16     int rx;
17 };
18 
19 int main()
20 {
21     A a(4);
22     cout<<++a<<" "<<a++<<endl; //首先将参数的值求出,然后再压栈,在无括号的情况下求参的值是从右向左,因此首先求最右侧的参数a++
23     return 0;
24 }
25 //输出 6 4

26.重载输入运算符

当二元运算符重载函数 定义为成员函数时二元运算符只能带一个参数

即operator运算符(只能含一个参数)

解救方法:将此operator函数设置成friend;

 1 #include <iostream>
 2 using namespace std;
 3 class A
 4 {
 5 public:
 6     A(int i){x=i;}
 7     friend istream &operator>>(istream &s,  A &c)//重载输入运算符
 8     {
 9         s>>c.x;    
10         return s;
11     }
12     friend ostream &operator<<(ostream &o, const A &c)//重载输出运算符
13     {
14         o<<c.x;
15         return o;
16     }
17 private:
18     int x;
19 };
20 int main()
21 {
22     A a(3),b(4);
23     cin>>a>>b;
24     cout<<a<<b;
25     return 0;
26 }

27.编写一个String类

该类具有的功能:

  1 //完成后的String类的程序代码如下:
  2 #include <iostream>
  3 using namespace std;
  4 class String 
  5 {
  6 public:
  7     String();                            //默认构造函数用于创建空字符串
  8     ~String();
  9     String(const String&rs);
 10     String(const char*const ch);        //带一个参数的构造函数用来初始化字符串
 11     char&operator[](unsigned short int length);
 12     char operator[](unsigned short int length)const;//函数体前加const只能const函数才能调用,而且const函数体内不能调用非const函数。可防止基类函数被派生类修改
 13     String&operator=(const String&s);    //赋值函数用于两个字符串之间的赋值
 14     String operator+(const String &);
 15     void operator+=(const String&rs);
 16     friend ostream &operator<<(ostream & o, const String &str)
 17     {
 18         o<<str.str;
 19         return o;
 20     }
 21     friend istream &operator>>(istream&i, String &str)
 22     {
 23         i>>str.str;
 24         return i;
 25     }
 26     friend bool operator<(const String&str1,const String &str2)
 27     {
 28         if(strcmp(str1.str,str2.str)<0)
 29             return 1;
 30         else
 31             return 0;
 32     }
 33     friend bool operator>(const String&str1,const String &str2)
 34     {
 35         if(strcmp(str1.str,str2.str)>0)
 36             return 1;
 37         else
 38             return 0;
 39     }
 40     friend bool operator==(const String&str1,const String &str2)
 41     {
 42         if(strcmp(str1.str,str2.str)==0)
 43             return 1;
 44         else
 45             return 0;
 46     }
 47     unsigned short int getlen()const{return len;}
 48     const char*getstr()const{return str;}
 49 private:
 50     String(unsigned short int);
 51     unsigned short int len;
 52     char* str;
 53 
 54 };
 55 String::String(unsigned short int length)
 56 {
 57     str=new char[length+1];
 58     int i;
 59     for(i=0;i<=length;i++)
 60         str[i]='';
 61     len=length;
 62 }
 63 String::String()
 64 {
 65     len=0;
 66     str=new char[1];
 67     str[0]='';
 68 }
 69 String::~String()
 70 {
 71     delete []str;
 72     len=0;
 73 }
 74 String::String(const String&rs)
 75 {
 76     len=rs.getlen();
 77     str=new char[len+1];
 78     for(int i=0;i<len;i++)
 79         str[i]=rs[i];
 80     str[len]='';
 81 }
 82 String::String(const char*const ch)
 83 {
 84     len=strlen(ch);
 85     str=new char[len+1];
 86     for(int i=0;i<len;i++)
 87         str[i]=ch[i];
 88     str[len]='';
 89 }
 90 char&String::operator[](unsigned short int length)
 91 {
 92     if(length>len)
 93         return str[len-1];
 94     else
 95         return str[length];
 96 }
 97 char String::operator[](unsigned short int length)const
 98 {
 99     if (length>len)
100     {
101         return str[len-1];
102     }
103     else
104         return str[length];
105 }
106 String&String::operator=(const String&s)
107 {
108     if (this==&s)
109         return *this;
110     delete[]str;
111     len=s.getlen();
112     str=new char[len+1];
113     for(int i=0;i<len;i++)
114     {
115         str[i]=s[i];
116     }
117     str[len]='';
118     return *this;
119 }
120 String String::operator+(const String&rs)
121 {
122     int total=len+rs.getlen();
123     String temp(total);
124     int i,j;
125     for( i=0;i<len;i++)
126         temp[i]=str[i];
127     for( j=0;j<rs.getlen();j++,i++)
128         temp[i]=rs[j];
129     temp[total]='';
130     return temp;
131 }
132 void String::operator+=(const String&rs)
133 {
134     int total=len+rs.getlen();
135     String temp(total);
136     int i,j;
137     for(i=0;i<len;i++)
138         temp[i]=str[i];
139     for(j=0;j<rs.getlen();j++,i++)
140         temp[i]=rs[j];
141     temp[total]='';
142     *this=temp;
143 }
144 int main()
145 {
146     String s1;
147     cout<<"s1的长度:"<<s1.getlen()<<endl;
148     char*temp="help me";
149     s1=temp;
150     cout<<"s1:"<<s1.getstr()<<"	 s1的长度:"<<s1.getlen()<<endl;
151     char ch[10];
152     strcpy(ch,"all right");
153     s1+=ch;
154     cout<<"ch:	"<<ch<<endl;
155     cout<<"s1:	"<<s1.getstr()<<endl;
156     cout<<"s1:"<<s1<<endl;
157     s1[2]='o';
158     cout<<"s1:"<<s1<<endl;
159     cout<<"s1[999]:"<<s1[999]<<endl;
160     String s2="mother";
161     String s3("Mother");
162     cout<<"s2:"<<s2<<"	 s3:"<<s3<<endl;
163     String s4=s2+s3;
164     cout<<"s2+s3="<<s4<<endl;
165     int check=s2>s3;
166     cout<<"s2>s3:"<<check<<endl;
167     check=s2<s3;
168     cout<<"s2<s3:"<<check<<endl;
169     check=s2==s2;
170     cout<<"s2==s2:"<<check<<endl;
171     cin>>s2[0]>>s3[0];
172     s2=s2+s3;
173     cout<<"s2:"<<"	"<<s2<<endl;
174     return 0;
175 }

38.总结

原文地址:https://www.cnblogs.com/zenseven/p/3800777.html