文章目录
学习内容
一、字符串的定义
1.字符串是存储在内存的连续字节的一系列字符。
2.C++中处理字符串的方式有两种:
(1)C语言风格字符串。——以空字符“\0”结尾的字符串。
(2)基于string类进行处理字符串。
二、字符串的处理操作(C语言风格字符串)
1.字符串初始化
(1)显示写空字符
char name[4] = {'B','o','b','\0'}; //数组的长度一定要大于字符个数+‘\0’的个数
char name[4] = {'B','o','b'}; //这个不是一个字符串,原因是没有写空字符。
注意:空字符在这种初始化的时候,一定不能遗漏;其次,数组的长度应该足够大,必须包含空字符在内,原因是字符串处理是遇到空字符停止,而不是根据字符串长度(C++中对字符串的长度不限制)。
(2)隐式不写空字符——字符串常量
char name[10] = "Bob"; //双引号括起来的字符串隐式包括了结尾的空字符。
//注意以下两种写法的区别
char name[] = "Bob"; //虽然字符串常量是常量,但由于数组也开辟了内存,实际存放的是字符串常量的副本,所以可以name[]可以被改写。
char *name = "Bob"; //指针指向字符串产量,所以该指针的内容是不可以改变的。
//一般将上面这行改成
const char *name = "Bob";
注意:
//字符串常量和字符常量的区别
char name = 'S'; //写法正确,字符常量
char name2 = "S"; //写法错误,字符串常量“S”实际是“S”和“\0”的组成,“S”相当于是该字符串的首地址,赋值给一个char类型,当然报错。
2.拼接字符串
- 任何两个由空白(空格、制表符、换行符)分隔的字符串常量都可以自动拼接成一个字符串。
cout << " I want to " "play game" <<endl; // 空格分隔 I want to play game
cout << " I want "
" to go home"<<endl; //I want to go home
- 调用strcat()函数来拼接
strcat()函数是在cstring头文件中(C++),或在string.h(C语言中)。
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char name[6] = "hello";
char name_new[16] = "bob";
//拼接时,存放新的字符串的数组空间需足够大
strcat(name_new, name); //存在风险,当拼接后的字符串大于name_new的容量时,会直接踩了后面的空间
cout << name_new << endl; //bobhello
//使用下面的更为安全
strncat(name_new, name, 3);//指明需要拼接的长度为3,也就是在name_new后拼接name的前3个字符
cout << name_new; //bobhellohel
return 0;
}
3.在数组中使用字符串
- 字符串数组初始化的两种方式:
char name[] = "Bob"; //(1)直接初始化为字符串常量;
char name2[10]; //(2)通过读入或者写入到数组中。
cin >> name2;
- sizeof和strlen的区别:
strlen是C++中的cstring文件中的函数,是C语言中string.h文件中的函数。
char name[10] = "Bob";
int a = sizeof(name)/sizeof(name[0]); //10 , sizeof返回的是数组的空间长度,而不是字符串的长度。
int b = strlen(name); //3 , strlen返回的是该字符串可见的字符长度,不包括空字符“\0”。
注意:所以数组的空间长度需要大于或等于strlen(name)+1;
- 数组字符串的访问及改写
数组字符串也可以通过数组索引访问和改写某位置上的字符。但是如果某位置上的值被改成“\0”,则该数组字符串将提前结束了。
char name[ ] = "gaoyang";
name[2] = "\0"; //字符串则会提前结束,字符串为“ga”
4.字符串的输入
- 通过cin来输入,cin在遇到空白(空格、制表符、换行符)来确定字符串的结束位置。
char name[10];
cin >>name; //当控制台输入:Bob Tom
//name数组中实际只有一个单词Bob,因为后面有空白,所以Tom并没有写入到name中。
2.通过getline()或get()获取某一行上的输入
(1)getline()和get()函数的共同点:
均是来自istream中的类成员函数;功能都是读取一行的输入,直到遇到换行符结束。
(2)getline()和get()函数的不同点:
getline()函数会将换行符丢弃; get()函数会将换行符保留在输入序列中。
#include <iostream>
using namespace std;
#define SIZE 20
int main()
{
#if 0
cout<<"***** getline() ******"<<endl;
char name[SIZE];
cout<<"Please input name:";
/*
getline()函数第一个入参表示要写入的地址;
第二个入参表示指定字符的数目(含空字符),例如为15,则最多有14个字符加一个空字符。
函数遇到回车键形成的换行符为结束。
*/
cin.getline(name, 15); //输入:Gao Yang 回车键
cout<<name<<endl; //Gao Yang 输出的字符串不含有回车键,但后面会自动补空字符。
#endif
cout<<"***** get() ******"<<endl;
char name2[SIZE];
char name3[SIZE];
cout<<"name2:";
/*
与getline()的两个参数的含义一样。只是get()函数读取一行后,回车键也保存在字符串中。
因此连续调用2次get()函数时,第二次调用直接遇到回车键就结束。
*/
cin.get(name2,10); //可以得到文字
cin.get(name3,8); //由于一上来就遇到了换行符,所以暂时没法获取第二行。
//可以多使用一个get(),来处理掉换行符
cout<<"***** 修改后 方法1 ******"<<endl; //成功分别读取2行
cin.get(name2,10).get();
cin.get(name3,8).get();
cout<<"***** 修改后 方法2 ******"<<endl;
cin.get(name2,10);
cin.get();
cin.get(name3,8);
cin.get();
return 0;
}
三、字符串的处理操作(基于string类的字符串)
1.如何使用string类
- 必须包含string的头文件,string类位于命名空间std中。
#include <string>
using namespace std;
- string类对象的创建和初始化
string var; //创建string类的对象
string var2 = "string init"; //创建对象的同时可以像char数组一样可以初始化
string var3 = {"string init"}; //C++11也允许string这样初始化
cout << var2 <<endl;
cin >> var; //也可以使用cin进行控制台输入
cout << var[2] << endl; //也可以像char数组一样进行访问字符串中的某个位置上的字符。
- string类对象和普通char数组的不同之处?
string声明的对象是一个普通变量,而不是数组;且string类对象会根据字符串的长度自动调整对象的长度。
char数组可以视为是存储一个字符串的char存储单元,string类对象是一个表示字符串的实体。
2.string类对象的操作
- 赋值及拼接
string var1 = "hello;
string var2;
string var3;
//赋值,string类可以这样操作,但数组就不能这样直接赋值。
var2 = var1;
//拼接
var3 = var1 + var2;
var3 += var1;
//对于C风格的字符串赋值,则需要借助cstring中的strcpy函数
char name_new[10], name_old[10];
strcpy(name_new, name_old); //从old中赋值给new中。
- 求字符串的长度
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main()
{
int temp;
//C风格的字符串
char name[10] = "hello";
temp = sizeof(name); //char为1字符,相当于sizeof(name)/sizeof(name[0],求数组的存储长度
cout << temp <<endl; //10
temp = strlen(name); //求数组字符串真实长度(不包含空字符),直到遇到空字符就不计算了。
cout << temp <<endl; //5
//string类对象的字符串
string str = "bob";
cout << str.size() <<endl; //3,求数组真实长度(不包含空字符)
char varb[20];
string varb2;
int Len1 = strlen(varb); //为随机值,原因是未被初始化的char数组,其值是随机的,而strlen是遇到空字符才停止计数,空字符又是随机出现。
int Len2 = varb2.size(); //0 原因是未被初始化的string类对象会自动将长度置为0.
return 0;
}
- 读取输入行的字符串
char var[10];
cin.getline(var,10);//入参第一个写入首地址,写入长度为9个字符加上1个空字符。
string str;
getline(cin,str); //一个参数表示在cin对象中找getline方法,写入到对象str中,不用写长度是应为string类自动会根据字符串调整长度。