当我们想要向计算机当中存储一句话,或者很多字符的时候,我们就会使用到字符数组
字符数组的定义如下:
char a[100] = {'0'};
与定义普通数组一样,采用 类型 变量名[] 的形式来进行定义,字符数组可以用于存储多个字符,
用双引号包括起来的中间字符组成的序列叫做
字符串的定义如下:
char n[] = "hello,world";
字符数组和字符串的区别:两者都是使用char来定义,区别在于字符串在存储时在末尾
字符串
存在一个'\0'的结束标志,这个标志也占据数据的一个实际位置
字符串作为一个特殊的字符数组,可以按照数组元素逐个处理,也可以直接使用cin和cout语句完成输入输出
#include <iostream>
using namespace std;
int main(){
//定义一个空字符串
char a[] = "";
cin >> a ; //字符串输入
cout << a ; //字符串输出
return 0;
}
C风格字符串函数的使用
名称 | 函数 | 作用 |
---|---|---|
长度 | strlen(s1); | 返回字符串s1的长度(不包含'\0') |
复制 | strcpy(s1,s2); | 给s1赋值,值为s2 |
拼接 | strcat(s1,s2); | 在s1的末尾拼接s2 |
比较 | strcmp(s1,s2); | s1 == s2;返回0 s1 < s2;返回负数 s1 > s2;返回正数 |
使用案例
使用这些函数,必须包含头文件<cstring>
#include <iostream>
#include <cstring>
using namespace std;
int main(){
char s1[20] = "Hello";
char s2[20] = "World";
char s3[20] = "";
cout << "s1的长度为:" << strlen(s1) << endl;
cout << "s2的长度为:" << strlen(s1) << endl;
//将s1复制到s3中
strcpy(s3,s1);
cout << "s3的内容为:" << s3 << endl;
cout << "s2的内容为: " << s2 << endl;
//将s2拼接在s1的末尾
strcat(s1,s2);
cout << "s1的内容为:" << s1 << endl;
return 0;
}
问题
输入一个长度不超过100且不包含空格的字符串,统计输出这个字符串中字符'a'的个数和这个字符串中所有有效字符的个数,使用空格分割
输入:aabbcc
输入:aabbcc
输出:2 6
问题分析:
1.字符串最后会有一个'\0'结尾,定义一个长度为101的字符串
2.需要统计a的个数和总字符数,因此需要两个用于计数的变量
3.开始进行遍历,统计数量
示例代码
#include <iostream>
#include <cstring>
using namespace std;
int main(){
char a[101] = "";
int k = 0,n = 0;
cin >> a;
for (int i = 0 ;i < strlen(a);i++){ //遍历字符数组当中的每一个数组
if (a[i] == 'a'){
k++;
}
n++;
}
cout << k << " " << n <<endl; //输出结果
}
问题
输入得到一段加密后没有空格的字符串,长度不超过1000。
加密规则:所有数字字符不变,大写和小写字符之间相互转换。编写程序完成密文的解密并输出
输入:abcda
输出:ABCDA
问题分析:
1.字符串最后会有一个'\0'结尾,定义一个长度为1001的字符串
2.如果字符在65-90之间,是一个大写字母,如果字符在97-122之间,则是一个小写字母,大小写字母之间间隔32
3.开始进行遍历,进行逐个转换
#include <iostream>
#include <cstring>
using namespace std;
int main(){
char n[1001] = "";
cin >> n;
//开始进行遍历,逐个进行判断
for (int i = 0;i < strlen(n);i++){
if (n[i] >= 65 && n[i] <= 90){ //如果是大写,则加32
n[i] = n[i] + 32;
}
if (n[i] >= 97 && n[i] <= 122){ //如果是小写,则减32
n[i] = n[i] - 32;
}
}
cout << n;
}
示例代码
问题
输入一个长度不超过100且不包含空格的字符串,判断这个字符串是否为回文字符串。
如果是则输出OK,否则输出ERROR
输入:ocffco
输出:OK
回文字符串:字符串从前向后和从后向前的字符顺序一样
输入:offfce
输出:ERROR
#include <iostream>
#include <cstring>
using namespace std;
int main(){
char a[1001] = "";
cin >> a;
int i,j;
int n = (strlen(a) - 1) >> 1;
//开始遍历,一旦发现a[i]和b[i]不相等,则说明不是回文
for(i = 0,j = strlen(a) - 1;i < n ;i++,j--){
if (a[i] != a[j]){
break;
}
}
//如果已经遍历完毕,则说明是回文数字,否则不是
if (i == n){
cout << "OK" << endl;
}else{
cout << "ERROR" << endl;
}
}
示例代码
C语言风格字符串的特点:
string类也叫字符串,是C++标准库把字符数组封装起来的类。而且,string类具有更多的特性功能
//采用 类型 变量名;
string str;
声明string类型的格式如下:
//采用 类型 变量名;
string str = "hello world";
string类型的初始化格式如下:
表达式 | 功能 |
---|---|
s1 += s2 | 将s2拼接在s1后面 |
s1 = s2 | 将s2的值赋给s1 |
s1 == s2 | 判断2个字符串是否相等 |
s1 < s2 | 判断s1是否小于s2 |
s1[i] | 访问s1中下标为i的字符 |
string类的基本操作
string类的基本功能
表达式 | 功能 |
---|---|
s1.length()/s1.size() | 返回s1字符串的长度 |
s1.substr(a,b) | 截取s1中下标为a到b的字符串 |
s1.insert(a,'s') | 在s1中下标为a的位置插入字符s |
使用案例
#include <iostream>
#include <string>
using namespace std;
int main(){
string s1 = "Hello";
string s2 = "World";
cout << "s1的长度:" << s1.length() << endl;
cout << "s2的长度:" << s1.size() << endl;
cout << "截取s1的下标2到4的元素:" << s1.substr(2,4) << endl;
cout << "将s1和s2进行连接:" << s1 + "," + s2 << endl;
s1.insert(5,'c');
cout << "在s1的下标5的位置插入字母c:" << s1 << endl;
return 0;
}
字符串的输入
使用cin来输入字符串,当字符串中包含空格的时候输入就会停止,后面的数据就会接收不到。
//数组字符串的输入格式:
cin.getline(数组名,长度);
gets(数组名)
//string字符串的输入格式:
getline(cin,string变量名);
输入案例
#include <iostream>
#include <string>
using namespace std;
int main(){
string s1;
//遇到空格就会停止
cin >> s1;
cout << s1 << endl;
}
#include <iostream>
#include <string>
using namespace std;
int main(){
string s1;
//会读取空格
getline(cin,s1);
cout << s1 << endl;
}
问题2.1
输入2行不超过100,只包含数字和空格的字符串,编写程序判断在忽略空格的前提下,2个字符串是否一样,如一样输出“YES”,否则输出“NO”
输入:
hel lo
hello
输出:YES
问题分析:
1.由于输入可能会有空格,因此使用getline()函数来获取输入
2.对两个字符串进行遍历,如果遇到空格,则跳过,发现有不同的字符存在,则结束循环
3.输出最后的结果
#include <iostream>
#include <string>
using namespace std;
int main(){
string s1;
string s2;
int i = 0,j = 0; //定义两个变量,用于遍历
getline(cin,s1); //用getline获得两个输入
getline(cin,s2);
cout << s1 << endl;
cout << s2 << endl;
while(i < s1.length() || j < s2.length()){ //对两个字符串进行遍历
if (s1[i] == ' '){ //发现s1有空格,则跳过
i++;
}
if(s2[j] == ' '){ //发现s2有空格,则跳过
j++;
}
if (s1[i] != s2[j]) break; //发现有不同的字符,则退出遍历
i++;j++;
}
if (i == s1.length() || j == s1.length()){ //其中一个已经遍历完成,则说明是相同的,否则不相同
cout << "YES" << endl;
}else{
cout << "NO" << endl;
}
}
问题2.2
输入一行包含空格且长度不超过100的字符串,统计其中的大写和小写字母的个数,如果大写字母多就输出“Y”,小写字母多久输出“N”,相等输出“O”
输入:Good
输出:N
#include <iostream>
#include <string>
using namespace std;
int main(){
string s1;
int j = 0,k = 0;
getline(cin,s1);
for (int i = 0;i < s1.length();i++){
if (s1[i] == 'O') j++;
if (s1[i] == 'o') k++;
}
if (j > k){
cout << "Y" << endl;
}else if (j == k){
cout << "O" << endl;
}else{
cout << "N" << endl;
}
}
在有的时候,我们可能需要存储多句话,我们可以定义多个字符串来存储
char s1[100] = "";
char s2[100] = "";
char s3[100] = "";
cin >> s1;
cin >> s2;
cin >> s3;
但如果我们要存储很多句话,我们不能单个去定义,我们可以使用二维字符数组
char s[10][100];
以上定义了一个二维字符数组,表示10个大小为100的字符数组
我们可以通过循环的方式不断获取10个输入
#include <iostream>
#include <cstring>
using namespace std;
int main(){
char s[10][100];
//因为有10个大小为100的字符数组,需要进行10次输入
for (int i = 0;i < 10 ;i++){
cin >> s[i];
}
//输出结果
for (int i = 0;i < 10 ;i++){
cout << s[i] << endl;;
}
}
问题3.1(P2431)
给定一个不包含空格的字符串,判断是否是C语言合法的标识符号(注:题目保证这些字符串一定不是C语言的保留字)
输入:RKPEGX9R;TWyYcp
输出:NO
#include <iostream>
#include <string>
using namespace std;
int main(){
string s1;
string s2[] = {"for","while","if","else","int","float"};
int flag = 0; //设置标志,为1则合法
cin >> s1; //获得输入,不能有空格出现
for (int i = 0;i< s1.length();i++){
if (s1[0] >= 48 && s1[0] <= 57){ //如果发现第一个字符是数字,则直接判断不是合法的
flag = 0;
break;
}
//判断每个字符是否是数字、字母和"_",如果不是,则直接判断不是合法的
if ((s1[i] >= 48 && s1[i] <= 57) || (s1[i] >= 97 && s1[i] <= 122) || (s1[i] >= 65 && s1[i] <= 90) || (s1[i] == '_') ){
flag = 1;
}else{
flag = 0;
break;
}
}
//判断是否为C语言中已经使用的关键字,关键字列表在上面定义
for (int i = 0; i < 6;i++){
if (s1 == s2[i]){
flag = 0;
break;}
}
//输出结果
if (flag){
cout << "YES" << endl;
}else{
cout << "NO" << endl;
}
}
问题3.2
给定一个只包含小写字母的字符串,请找到第1个仅出现一次的字符。如果没有,输出“NO”
输入:adhaahhb
输出:d
#include <iostream>
#include <string>
using namespace std;
int main(){
int result[26] = {0};
int i;
string s1;
cin >> s1;
//遍历进行统计
for (i= 0;i<s1.length();i++){
result[s1[i] - 97]++;
}
//找出第1个仅出现一次的字符
for (i = 0;i< s1.length();i++){
if (result[s1[i] - 97] == 1){
cout << s1[i] << endl;
break;
}
}
//如果发现没有1次的,则输出结果
if (i == s1.length()){
cout << "NO" << endl;
}
}