天天看点

C++之字符串总结

文章目录

      • 1.字符串声名
      • 2.面向行的输入
      • 3.string类简介
        • 3.1 C++11 字符串初始化
        • 3.2 赋值、拼接和附加
        • 3.3 string 其他操作

1.字符串声名

字符串是存储在内存的连续字节中的一系列字符。C++处理字符串的方式有两种。第一种来自C语言,常被称为C风格字符串(C- style string)。另一种基于 string类库的方法。

存储在连续字节中的一系列字符意味着可以将字符串存储在char数组中,其中每个字符都位于自己的数组元素中。C风格字符串具有一种特殊的性质:以空字符( null character)结尾,空字符被写作\0,其 ASCII I码为0,用来标记字符串的结尾。例如,请看下面两个声明

char dog[8]={'b','e','a','u',' ','I','i'};       // not a string!
char dog[8]={'f','a','t','e','s','s','a','\0'};   // a string!
           

这两个数组都是char数组,但只有第二个数组是字符串。空字符对C风格字符串而言至关重要。例如C++有很多处理字符串的函数,其中包括cout使用的那些函数。它们都逐个地处理字符串中的字符,直到达空字符为止。如果使用cout显示上面的cat这样的字符串,则将显示前7个字符,发现空字符后停止但是,如果使用cout显示上面的dog数组(它不是字符串),cout将打印出数组中的8个字母,并接着内存中随后的各个字节解释为要打印的字符,直到遇到空字符为止。由于空字符(实际上是被设置为0的字节)在内存中很常见,因此这一过程将很快停止。但尽管如此,还是不应将不是字符串的字符数组当作字符串处理。

  • 字符串的简化定义

只需使用一个用引号括起的字符串即可,这种字符串被称为字符串常量( string constant)或字符串字面值( string literal),如下所示:

char bird[11] = "Mr. Cheeps"; 
char fish[] = "Bubbles";
           

用引号扩起的字符串隐式的包括了结尾的空字符(’\0’),当然,应确保数组足够大,能够存储字符串中所有字符—包括空字符。使用字符串常量初始化字符数组是这样的一种情况,即让编译器计算元素数目更为安全。让数组比字符串长没有什么害处,只是会浪费一些空间而已。这是因为处理字符串的函数根据空字符的位置,而不是数组长度来进行处理。C++对字符串长度没有限制

C++之字符串总结
注意,字符串常量(使用双引号)不能与字符常量(使用单引号)互换。字符常量(如’S’)是字符串编码的简写表示。在ASCⅡ系统上,'S’只是83的另一种写法,因此,下面的语句将83赋给shirt_size
char shirt_size = 's';      // that's fine
           

但"S"不是字符常量,它表示的是两个字符(字符S和\0)组成的字符串。更糟糕的是,"S"实际表示是字符串所在的内存地址,因此下面的语句试图将一个内存地址赋给shirt_size;

char shirt_size = "S";  // illegal type mismatch
           

2.面向行的输入

1、cin.getline()

getline()函数读取整行,它使用通过回车键输入的换行符来确定输入结尾。要调用这种方法,可以使用 cin.getline()。该函数有两个参数。第一个参数是用来存储输入行的数组的名称,第二个参数是要读取的字符数。如果这个参数为20,则函数最多读取19个字符,余下的空间用于存储自动在结尾处添加的空字符。 getline()成员函数在读取指定数目的字符或遇到换行符时停止读取。例如,假设要使用 getline()将姓名读入到一个包含20个元素的name数组中。可以使用这样的函数调用:

cin.getline(name,20)
           
C++之字符串总结

getline()函数每次读取一行。它通过换行符来确定行尾,但不保存换行符。相反,在存储字符串时,它用空字符来替换换行符(参见图4.5)

2、cin.get()

我们来试试另一种方法。 Istream类有另一个名为get()的成员函数,该函数有几种变体。其中一种变体的工作方式与 getline()类似,它们接受的参数相同,解释参数的方式也相同,并且都读取到行尾。但get并不再读取并丢弃换行符,而是将其留在输入队列中。假设我们连续两次调用get():

cin.get(name,ArSize);
cin.get(dessert,ArSize); // a problem
           

由于第一次调用后,换行符将留在输入队列中,因此第二次调用时看到的第一个字符便是换行符。因此get()认为已到达行尾,而没有发现任何可读取的内容。如果不借助于帮助,get()将不能跨过该换行符幸运的是,get()有另一种变体。使用不带任何参数的 cin.get()调用可读取下一个字符(即使是换行符),因此可以用它来处理换行符,为读取下一行输入做好准备。也就是说,可以采用下面的调用序列:

cin.get(name,ArSize);        //read first line
cin.get()                    //read new line
cin.get(dessert,Arsize);     // read second line
           

另一种使用get()的方式是将两个类成员函数拼接起来(合并),如下所示:

cin.get(name,ArSize).get();   //concatenate member functions
           

之所以可以这样做,是由于 cin. get(name, AsSize)返回一个cin对象,该对象随后将被用来调用get()函数。同样,下面的语句将把输入中连续的两行分别读入到数组name1和name2中,其效果与两次调用cin.getline()相同

cin.getline(naem1,ArSize).getline(name2,ArSize)
           

3.string类简介

ISO/ANSI C++98标准通过添加 string类扩展了C++库,因此现在可以 string类型的变量(使用C+的话说是对象)而不是字符数组来存储字符串。您将看到, string类使用起来比数组简单,同时提供了将字符串作为一种数据类型的表示方法。要使用 string类,必须在程序中包含头文件 string。 string类位于名称空间std中,因此您必须提供一条using编译指令,或者使用std::string来引用它。 string类定义隐藏了字符串的数组性质,让您能够像处理普通变量那样处理字符串。

string str1;      //creat an empty string object
string str2 = "panther";   //creat an initialized string
           

类设计让程序能够自动处理 string的大小。例如,strl的声明创建一个长度为0的 string对象,但程序将输入读取到sr1中时,将自动调整strl的长度:

cin >> str1;    //str1 resized to fit input
           

这使得与使用数组相比,使用 string对象更方便,也更安全。从理论上说,可以将char数组视为一组用于存储一个字符串的char存储单元,而 string类变量是一个表示字符串的实体。

3.1 C++11 字符串初始化

char first_data[] = {"le Charpin Dodu"};
char second_data[] {"The Elegant Plate"};
string third_data = {"The Bread Bowl"};
string fourth_data {"Hank Fine Eats"};
           

3.2 赋值、拼接和附加

使用 string类时,某些操作比使用数组时更简单。例如,不能将一个数组赋给另一个数组,但可以将一个 string对象赋给另一个 string对象:

char charrl[20];     //create an empty array 
char charr2[20]="jaguar";  //create an initialized array
string str1;         //create an empty string object 
string str2 ="panther";   //create an initialized string 
charr1 = charr2;    //INVALID, no array assignment
strl = str2;       //VALID, object assignment ok
           

string类简化了字符串合并操作,可以使用运算符+将两个string对象合并起来,还可以使用运算符符串+=附加到 string对象的末尾。继续前面的代码,可以这样做:

sting str3;
str3 = str1 + str2;     //assign str3 the joined strings
str1 += str2;         // add str2 to the end of str1
           

3.3 string 其他操作

在C++新增 string类之前,程序员也需要完成诸如给字符串赋值等工作。对于C风格字符串程序员使用C语言库中的函数来完成这些任务。头文件 cstring(以前为 string. h)提供了这些函数。例如,可以使用函数 strcpy()将字符串复制到字符数组中,使用函数 strcat()将字符串附加到字符数组末尾:

strcpy(charr1,charr2);   //copy charr2 to charr1
strcat(charr1,charr2);   //append contents of charr2 to charr1
strlen(charr1);          // return the length of charr1
           

string类提供了一系列针对字符串的操作

1.append()-- 在字符串的末尾添加字符

2.find()–在字符串中查找字符串

3.insert()–插入字符

4.length()–返回字符串的长度

5.replace()–替换字符串

6.substr()–返回某个字符串

#include <iostream>
#include <string>
using namespace std;

int main()
{
    //定义一个string类对象
    string http = "www.runoob.com";

   //打印字符串长度
   cout<<http.length()<<endl;

    //拼接
    http.append("/C++");
    cout<<http<<endl; //打印结果为:www.runoob.com/C++

    //删除
    int pos = http.find("/C++"); //查找"C++"在字符串中的位置
    cout<<pos<<endl;
    http.replace(pos, 4, "");   //从位置pos开始,之后的4个字符替换为空,即删除
    cout<<http<<endl;

    //找子串runoob
    int first = http.find_first_of("."); //从头开始寻找字符'.'的位置
    int last = http.find_last_of(".");   //从尾开始寻找字符'.'的位置
    cout<<http.substr(first+1, last-first-1)<<endl; //提取"runoob"子串并打印

    return 0;
}
           

继续阅读