一句话与多句话

字符数组与字符串

当我们想要向计算机当中存储一句话,或者很多字符的时候,我们就会使用到字符数组

字符数组的定义如下:

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;
    }
    
}

示例代码

String类

C语言风格字符串的特点:

  1. 执行拷贝、比较等操作,都需要调用函数
  2. 字符串长度大于分配空间时,下标会越界

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;
    }
}
Made with Slides.com