分类
Level3

字符数组

字符串是计算机与人类沟通的重要手段。

一、字符数组 使用字符数组保存字符串时,末尾加上结束符’\0’,’\0’是字符数组结尾的标记。
可以使用字符串来初始化字符数组,但此时要注意,每个字符串结尾会暗含一个’\0’字符,因此字符数组的长度至少要比字符串的长度多1!

#include <iostream> 
using namespace std;
int main(){
    char a1[]={'C','+','+',0}; //0是'\0'的编码
    char a2[]={'C','+','+','\0'}; //效果同a1
    char a3[]="C++"; //不用写 \0 字符 
    char a4[6]="hongli";//错,没有空间存储,要给\0留位置 
    return 0;
}

字符数组的输入输出:

#include <iostream> 
using namespace std;
int main(){
    char a1[100]={'C','+','+'}; 
    cin>>a1; //输入字符串,遇到空格或回车就停止
    cout<<a1<<endl; //输出字符串,遇到空格或回车不会停止
    return 0;
}

读入一行字符串,包括空格:

#include <iostream> 
using namespace std;
int main(){
    char a[100]={'C','+','+'}; 
    fgets(a,sizeof(a),stdin); //读入带空格字符串
    puts(a);  //比cout还简洁,作用一样
    return 0;
}

字符数组的常用函数

#include <cstring>
(1) strlen(str),求字符串的长度
(2) strcmp(a, b),比较两个字符串的大小,a < b 返回-1,a == b 返回0,a > b返回1。这里的比较方式是字典序!
(3) strcpy(a, b),将字符串b复制给从a开始的字符数组。
(4) strcat(a, b), 把字符数组b接到字符数组a后面。
#include <iostream> 
#include <cstring> 
using namespace std;
int main(){
    char a[100]="hello world!",b[100]; 
    cout<<strlen(a)<<endl;  //长度 
    strcpy(b,a);  //将a的值拷贝给b 
    cout<<strcmp(a,b)<<endl; //比较,相等输出0 
    cout<<strcat(a,b)<<endl; //把字符数组b接到字符数组后面
    return 0;
}

遍历字符数组中的字符:

#include <iostream> 
#include <cstring> 
using namespace std;
int main(){
    char a[100]="hello world!"; 
    for(int i=0;i<strlen(a);i++)//遍历a每个字符
        cout<<a[i];//最后1个有效字符的下标是strlen(a)-1
    return 0;
}

二、String类型 string是C++的STL (Standard Template Library即标准模板库)提供的字符串类型,表示可变长的字符序列。字符串string类型的变量可以存储字符串。string是一种顺序表的结构,每个元素都是char类型的字符

string定义和初始化

string str1;
str1 = "hello";
string str2(str1);
string str3("world")
string str4(4, 'a'); // str4="aaaa";
str2 = str1;  //赋值,用str1内容副本替换掉str2的内容

string输入输出

cin>>str1;   //不带空格的一行
getline(cin, str1);  //带空格的一行
cout<<str1;  //输出字符串全部
printf(“%s”, s.c_str()); //不能直接用printf输出string,需要先转换
#include <iostream> //示例代码
#include <string>  //需要引入头文件string
using namespace std;
int main(){
    string s="hello world!"; 
    cout<<s<<endl;
    printf("%s\n",s.c_str()); //string转成char数组输出

    getline(cin, s);
    cout<<s<<endl;
    return 0;
}

string的长度

#include <iostream> 
#include <string> 
using namespace std;
int main(){
    string s1="hello world!", s2=""; 
    cout<<s1.empty()<<endl;  //判空,输出0
    cout<<s2.empty()<<endl;  //为空,输出1
    cout<<s2.size()<<endl;   //获取字符串长度,输出0
    cout<<s2.length()<<endl; //获取字符串长度,输出0
    return 0;
}

string的遍历访问 string 对象的下标从 0 开始。如果 s 是一个 string 对象且 s 不空,则 s[0] 就是字符串的第一个字符, s[1] 就表示第二个字符,而 s[s.size() – 1] 则表示 s 的最后一个字符。

string s="hello world!";
for(int i=0;i<s.size();i++)    cout<<s[i];  //遍历字符串每个下标

C++11中提供了基于范围的for循环,可以用于字符串遍历
for(char c:s) cout<<c<<endl;  //输出s的每个字符
for(char &c:s) c='a';  //将s的每个字符替换成a
cout<<s<<endl;

string的加法运算和比较运算

str1 = str1+str2;  //直接相加,就是将两个字符串连接在一起
str1 += str2;
str1.append(str2);
// 比较 <  <=  == != >  >=
// 以下返回值:
// 小于 0 表示当前的字符串小;
// 等于 0 表示两个字符串相等;
// 大于 0 表示另一个字符串小。
str1 > str2;
str1 == str2;

当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string:
string s1 = "hello", s2 = "world";
string s3 = s1 + ", " + s2 + '\n';
string s4 = s1 + ", ";	//正确:把一个string对象和有一个字面值相加
string s5 = "hello" +", "; //错误:两个运算对象都不是string
string s6 = s1 + ", " + "world"; //正确,每个加法运算都有一个运算符是string
string s7 = “hello” + ", " + s2;  //错误:不能把字面值直接相加,运算是从左到右进行的

string查找函数和截取函数
√ find(子串substr): 査找子字符串第一次出现的下标,没有则返回string: :npos (注意判断其为-1)。
√ find(substr, x): 在字符串的下标x之后,査找子串substr。
√ substr(开始位置i,子串长度len): 截取子字符串,当len>字符串长度的时候, 只取剩余的。
√ substr(开始位置i): 截取子字符串,从下标为i开始截取到最后。
string的删除、插入和替换
√ erase (开始下标i,删除长度len):删除字符串第i个下标开始的len个字符;
√ erase (开始下标i):删除字符串第i个下标开始往后的所有字符;
√ insert (插入下标,插入字符串s): 在字符串下标为i的位置插入一个字符串s;
√ replace(i, len, str): 从下标为i开始,替换len个字符为str。
字符类型判断函数:(非string函数)
√ isalpha(c):判断c是否为字母
√ islower(c):判断是否为小写
√ isupper(c):判断是否为大写
√ isdigit(c):判断是否为数字说明:返回非0表示真,返回0表示假;
字符类型转换函数:(非string函数)
√ tolower(c):字符转小写
√ toupper(c):字符转大写说明:返回int ;
排序和倒序函数:(非string函数)
√ sort(起始地址,结束地址+1):数组升序排序
√ reverse(起始地址,结束地址+1):数组逆序获取头尾指针
√ s.begin():获取字符串s的头位置(指针 )
√ s.end():获取字符串s的尾位置(指针 )
类型转换函数
√ stoi(s):将字符串s转换为对应的整数
√ stol(s):将字符串s转换为对应的longlong
√ stof(s):将字符串s转换为对应的float
√ to_string(int n):将整数n转换为字符串(本功能需要C++11的语法支持)
√ to_string(double a):将double型的a转为字符串转换成的字符串小数点后有6位(本功能需要C++11的语法支持)

cstring或string.h
string s和char s[]有什么区别?
(1)字符数组本质上还是数组,因此长度固定;string可以理解为长度不限的字符串;
(2)   字符数组的系统定义的函数过少,导致操作不方便;string集成大量的系统函数, 方便操作;
(3)   字符数组由于本质是数组,因此不能进行比较运算以及+运算;string可以直接做比较和+运算。
string提供了字符串操作常见的函数,方便在具体问题中直接调用。
(1)   长度可以理解为不限定。
(2)   string可以做加法(相当于连接起来),可以比较大小!
(3)   string有很多系统定义函数,方便我们编程。
注意:可以将string理解成一个特殊的数组:字符数组。

附:
sstream
sscanf和sprintf