目录
字符串的形式和储存
字符串的三种形式
1、用双引号括起来的字符串常量,如"CHINA","C++program"
2、存放于字符数组中,以"\0"字符(ASCII码为0)结尾。
3、string对象。string是C++标准模板库里的一个类,专门用于处理字符串(略)
字符串常量
1、字符串常量 占据内存的字节数=字符串字符数目+1,多出来的是结尾字符'\0'。
比如“C program”在内存中的布局:
2、当然,字符串长度是不包括‘\0’的。
3、”“也是合法字符串常量,叫做空串。空串也会占据一个字节的存储空间,存放'\0'。
4、字符串常量中若包含双引号,双引号应写为' \" '
'\'字符在字符串中出现时,应连写两次,变成'\\'。如下:
cout<<"He said:\"I am \\a student.\"";
用一维char数组存放字符串
1、包含'\0'字符的一维char数组,就是一个字符串。其中存放的字符串即 为'\0'前面的字符组成。
2、用char数组存放字符串,数组元素个数要至少为 字符串长度+1
3、char数组的内容,可在初始化时设定,也可以用C++库函数来修改,也可以用 对数组元素赋值 的方法来 改变其中的某一个字符。
4、字符串也可用cout,printf输出,用cin,scanf读入。
用cin,scanf读入时,会自动在字符串的末尾加上'\0'
输入字符串
用scanf输入字符串
scanf可以将字符串读入数组。
scanf会自动添加结尾的‘\0’。在数组长度不足时,scanf可能导致数组越界。比如char line[5],输入“12345”时数组越界,因为加上'\0'一共是6个元素。
scanf读入到空格为止。
#include<iostream>
using namespace std;
int main()
{
char line[100];
scanf("%s",line);
printf("%s",line);
}
用cin.getline读入一行到字符数组
cin.getline(char buf[],bufSize);
读入一行(行长度不超过bufSize-1),自动添加'\0'回车换行符不会写入buf,但是会从输入流中去掉。
#include<iostream>
using namespace std;
int main()
{
char line[10];
cin.getline(line,sizeof(line));
cout<<line;
}
字符串库函数
使用字符串函数需要 #include<cstring>
字符串函数都需要根据'\0'来判断字符串结尾
形参为char[ ]类型,实参就可以是char数组或字符串常量
字符串拷贝
strcpy(char dest[],char src[]);//拷贝src到dest
字符串比较大小
int strcmp(char s1[],char s2[]);//返回0则相等(长度相同且每个字符都相同),返回负数则s1<s2,返回正数则s1>s2
求字符串长度(不包含字符串结尾的'\0')
int strlen(char s[]);
📍strlen常见糟糕用法,如下:
strlen每次执行都是需要时间的,且时间和字符长度成正比
每次循环都调用strlen,是效率上的很大浪费
char s[100]="test";
for(int i=0;i<strlen(s);i++) {
s[i]=s[i]+1;
}
改良:
法一:应取出s的长度存放在一个变量里,然后再循环时使用该变量。如下:
char s[100]="test";
int len=strlen(s);
for(int i=0;i<len;i++) {
s[i]=s[i]+1;
}
法二:利用s[i]==0作为条件,'\0'的ASCII码为0。如下:
char s[100]="test";
for(int i=0;s[i];i++) {
s[i]=s[i]+1;
}
字符串拼接
strcat(char s1[],char s2[]);//将s2拼接到s1后面
字符串转成大写
strupr(char []);
字符串转成小写
strlwr(char []);
字符串库函数用法示例
#include<iostream>
#include<cstring>
using namespace std;
void PrintSmall(char s1[],char s2[])
{
if(strcmp(s1,s2)<=0)//比较
cout<<s1;
else
cout<<s2;
}
int main()
{
char s1[30];
char s2[40];
char s3[100];
strcpy(s1,"Hello");//s1="Hello"//拷贝
strcpy(s2,s1);//s2="Hello"
cout<<"1)"<<s2<<endl;//输出 1)Hello
strcat(s1,",world");//s1="Hello,world"//拼接
cout<<"2)"<<s1<<endl;//输出 1)Hello,world
cout<<"3)"<<PrintSmall("abc",s2)<<endl;//输出 3)Hello
cout<<"4)"<<PrintSamll("abc","aaa")<<endl;//输出 4)aaa
int n=strlen(s2);//长度
cout<<"5)"<<n<<","<<strlen("abc")<<endl;//输出 5)5,3
strupr(s1);//改大写
cout<<"6)"<<s1<<endl;
return 0;
}
例题:编写判断字串的函数
编写一个函数int Strstr(char s1[],char s2[]);
如果s2不是s1的字串,返回-1
如果s2是s1的字串,返回其在s1中第一次出现的位置
空串是任何串的子串,且出现位置为0
思路:用数组存储字符串
因为要返回s2在s1中第一次出现的位置,所以需要设置一个变量i来存储位置,
需要一个变量i控制s1的下标
需要一个变量i控制s1的下标
#include<iostream>
#include<cstring>
using namespace std;
int Strstr(char s1[],char s2[])
{
for(int i=0;s1[i];i++) {
int k=i;
int j=0;
for( ;s2[j];j++,k++) {
if(s1[k]!=s2[j])
break;
}
if(s2[j]==0)
return i;
}
return -1;
}
int main()
{
char s1[50],s2[50];
cin.getline(s1,sizeof(s1));
cin.getline(s2,sizeof(s2));
cout<<Strstr(s1,s2);
}