C++青少年简明教程:字符类型、字符数组和字符串

news2025/1/13 13:27:01

C++青少年简明教程:字符类型、字符数组和字符串

在 C++ 语言中,处理文本数据的基础是字符类型 char,字符数组,以及标凌库中的字符串类 std::string。

C++中的char类型占用 1 字节的内存空间,用于存储单个ASCII字符。例如,字符'A'在ASCII编码中对应的值是65。

字符数组是一个可以存储多个字符的连续内存空间。你可以使用字符数组来存储一个字符串(即一系列字符,以空字符'\0'结尾)。如:

char str[10] = "Hello"; // 注意,这里实际上存储了"Hello\0",即字符串后有一个空字符作为结束符

字符数组可以通过循环逐个访问其元素,但在处理时必须小心维护 '\0' 结束符,以防止出现越界错误。字符数组通常被称为 C-风格字符串(C-style strings)。这种字符串表示方式来源于 C 语言,在 C++ 中仍然被广泛支持,主要因为历史兼容性和操作系统接口的要求。

字符串类,在C++中,std::string是一个类,用于处理字符串。它是C++标准库中的一部分,提供了许多方便的方法来操作字符串,如连接、比较、查找等。使用 std::string 类可以大大简化字符串的操作,并提高代码的安全性和可读性。

字符类型

在C++中,字符类型使用关键字char来定义。字符类型表示单个字符,包括数字、字母、符号等。字符类型的大小是一个字节(8位)。

字符类型变量只能存储一个字符,例如:

char c = 'A'; // 定义字符类型变量c,存储值为'A'

注意使用字符类型数据确实使用单引号(' ')。

空字符的 ASCII 码值为 0,因此,可以使用以下语句来表示空字符:

char c = '\0';

字符数组

字符数组是由字符组成的一维数组,包含多个字符元素。字符数组也有一维、二维、三维之分。

一维字符数组

c++中,可以使用字符类型数组来存储多个字符。字符类型数组是由多个字符类型变量组成的有序集合,即一串字符。可以使用花括号和逗号分隔符来初始化字符类型数组,也可以使用双引号来初始化字符类型数组,这样可以更容易地输入一串字符,而无需逐个输入每个字符。例如:

char str1[] = {'H', 'e', 'l', 'l', 'o'}; // 定义字符类型数组str1,但不是一个字符串

char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'}; // 定义字符类型数组str2,并且是一个字符串

char str3[] = "Hello"; // 定义并双引号进行初始化字符类型数组str3,并且是一个字符串

str2和str3是等价的。

字符类型数组可以用来存储字符串,字符数组以空字符('\0')作为结尾标识,表示字符串的结束。在使用双引号进行初始化时,编译器会自动在字符数组末尾添加一个空字符'\0',也就是说使用字符串字面值来初始化字符类型数组时,不需要明确地添加空字符。

一维字符数组和字符串的不同点:

1.字符串以空字符('\0')作为字符串的结束符,而字符数组没有特定的结束符。

2.字符串可以使用双引号("")来初始化,例如char str[] = "hello",而字符数组则需依次赋值,例如char arr[] = {'h', 'e', 'l', 'l', 'o'}或者char arr[] = "hello";(这种方式会在数组的末尾自动添加一个空字符)。

3.字符串可以使用一些针对字符串类型的函数,例如strlen()、strcpy()、strcmp()等等。字符数组也可以使用这些函数,但是需要对其具体的长度、空字符进行处理。

尽管字符数组可以用来处理字符串,但在C++中,通常推荐使用string类。

一维字符数组初始化

1.使用字符串字面值进行初始化:

char str[] = "Hello";

这会创建一个字符数组str,并将字符串字面值"Hello"复制到该数组中。注意,字符数组的大小会根据字符串的长度自动确定。

2.使用花括号初始化列表进行初始化:

char str[] = {'H', 'e', 'l', 'l', 'o', '\0'};

这里使用花括号{}来指定字符数组的初始元素,包括最后一个null字符('\0')。

3.逐个赋值:

char str[6];
str[0] = 'H';
str[1] = 'e';
str[2] = 'l';
str[3] = 'l';
str[4] = 'o';
str[5] = '\0';

这种方式需要逐个给字符数组的元素赋值,并确保最后一个元素是null字符('\0')。

4.使用strcpy函数进行赋值(需要包含头文件<cstring>):

char str[6];
strcpy(str, "Hello");

注意,无论使用哪种方式,都需要保证字符数组的容量足够大,能够容纳赋值的字符串。另外,字符串赋值时要确保最后一个字符是字符串的结尾符 '\0'即null字符。

一维字符数组和字符串(string)的关系

在C/C++中,字符串实际上是以字符数组的形式存储的,以null字符('\0')作为字符串的结束标志。因此,可以说字符串是字符数组的一种特殊情况。一维字符数组可以用于存储任意的字符序列,而字符串则是一个以null字符结尾的字符数组。

字符数组可以通过初始化或赋值来定义,而字符串只能通过初始化来定义。字符数组是定长的,而字符串长度可变。

注意,下面两句是有区别的:

char str[6] = {'H', 'e', 'l', 'l', 'o'};

char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

都是合法的。

第一种写法定义了一个包含5个字符的字符数组,初始化为指定的字符序列,但没有明确指定空字符('\0')。如果将其作为字符串使用,可能会导致访问越界或其他错误。

第二种写法定义了一个包含5个字符和一个空字符的字符数组,并且明确地将最后一个元素设置为空字符('\0')。这样就确保了数组以空字符结尾,可以被正确地当作字符串来处理。

【顺便提示:C语言中只有一种方式来表示字符串,那就是使用C-style string的字符数组(char array)。

C++中处理字符串的两种都可以:

1.C-style string的字符数组(char array):使用字符数组来表示和处理字符串。字符数组以null字符 '\0' 结尾,可以使用C风格的字符串函数来进行操作。这种方式需要手动管理内存,并且对于较长的字符串长度可能会有限制。

2.使用 string 类型:C++标准库提供了 string 类型(std::string),它是一个类模板。可以通过包含 <string> 头文件来使用 string 类型。string 类型提供了许多方便的字符串操作方法,它为字符串的处理提供了更高级的抽象和功能。】

一维字符数组简单示例:

#include <iostream>
using namespace std;

int main() {
    char str[] = "Hello, World!"; //长度自动确定
    cout << str << endl;  // 输出:Hello, World!

    return 0;
}

使用标准库函数printf、scanf、puts、gets等完成字符数组的输入输出需要引入<cstdio>头文件。该头文件是对<stdio.h>头文件的C++版本支持,其中包含了许多对输入输出操作有用的函数及变量。详情可参考 “C++的输入输出”一节。

★使用printf和scanf完成字符数组的输入输出:

#include <cstdio>

int main() {
    char str[50];

    // 从标准输入读取一个字符串到字符数组中
    printf("请输入字符串:");
    scanf("%s", str);

    // 将字符数组的内容打印到标准输出中
    printf("您输入的字符串是:%s\n", str);

    return 0;
}

★使用puts和gets完成字符数组的输入输出

#include <cstdio>

int main() {
    char str[50];

    // 从标准输入读取一个字符串到字符数组中
    printf("请输入字符串:");
    gets(str);

    // 将字符数组的内容打印到标准输出中
    puts("您输入的字符串是:");
    puts(str);

    return 0;
}

C++ 标准库提供了一些函数用来处理以 null 结尾的字符数组(C 风格字符串)。这些函数包括在 <cstring>(或 <string.h>)头文件中。常用的如:

strlen :用于返回指定字符串的长度(不包括空字符)。

strcpy :用于将一个字符串复制到另一个字符数组中。

strcat :用于将两个字符串进行拼接。

strcmp :用于比较两个字符串,并返回它们之间的区别。

strchr :用于在字符串中查找给定字符的第一个出现位置。

strstr :用于在字符串中查找给定字符串的第一个出现位置。

提示:这些函数需要引入 <cstring> (或 <string.h>)头文件。该头文件包含了 C++标准库中与C语言字符串操作相关的函数的声明。

#include <iostream>
#include <cstring>
using namespace std;

int main() {
    // 定义两个C风格字符串
    char str1[] = "Hello, World!";
    char str2[] = "C++";

    // 使用strlen计算字符串长度
    int length1 = strlen(str1);
    int length2 = strlen(str2);
    cout << "字符串1长度: " << length1 << endl;
    cout << "字符串2长度: " << length2 << endl;

    // 使用strcpy复制字符串
    char str3[100];
    strcpy(str3, str1);
    cout << "复制后的字符串: " << str3 << endl;

    // 使用strcat拼接字符串
    char str4[100];
    strcpy(str4, str1);
    strcat(str4, ", ");
    strcat(str4, str2);
    cout << "拼接后的字符串: " << str4 << endl;

    // 使用strcmp比较字符串
    if (strcmp(str1, str2) == 0) {
        cout << "两个字符串相等" << endl;
    } else {
        cout << "两个字符串不相等" << endl;
    }

    // 使用strchr查找字符
    char* found = strchr(str1, 'W');
    if (found != nullptr) {
        cout << "找到字符: " << *found << endl;
    } else {
        cout << "未找到字符" << endl;
    }

    // 使用strstr查找字符串
    char* found2 = strstr(str1, str2);
    if (found2 != nullptr) {
        cout << "找到字符串: " << found2 << endl;
    } else {
        cout << "未找到字符串" << endl;
    }

    return 0;
}

运行输出:

字符串1长度: 13
字符串2长度: 3
复制后的字符串: Hello, World!
拼接后的字符串: Hello, World!, C++
两个字符串不相等
找到字符: W
未找到字符串

对于字符数组重点掌握一维字符数组,下面简要介绍二维字符数组。

二维字符数组最常见的初始化方式

1:逐个初始化

    char charArray1[2][3] = {{'a', 'b', 'c'}, {'d', 'e', 'f'}};

2:使用字符串字面值初始化

    char charArray2[2][3] = {"ab", "cd"};

二维字符数组简单示例

#include <iostream>
using namespace std;

int main() {
     // 二维字符数组
    char str[][10] = {"Hello", "World"}; // 大小为2x10
    cout << "str[0]: " << str[0] << endl;
    cout << "str[1]: " << str[1] << endl;

    return 0;
}

输出:

str[0]: Hello
str[1]: World

字符串类(std::string

一般推荐在 C++ 程序中使用 std::string 类来处理字符串,除非有特定的性能要求或者需要与旧的 C 代码库互操作。利用 std::string 提高开发效率和程序的安全性。

要使用 std::string 类,你需要引入的是 <string> 头文件。

在C++中,string类是标准库提供的字符串类,它在<string>头文件中定义。string类提供了一系列成员函数和操作符,用于处理和操作字符串。string不属于STL(Standard Template Library)中的容器类,而是C++标准库(Standard Library)中的一个类,用于表示和操作字符串。

你可以很方便地使用string类进行字符串的赋值、拼接、查找、替换等操作,而不需要手动管理内存或考虑字符串长度的限制。

赋值和拼接:可以使用=操作符进行字符串的赋值,也可以使用+操作符进行字符串的拼接。

访问字符:可以使用下标操作符[]来访问字符串中的单个字符,并可以修改它们。

字符串长度:使用length()或size()成员函数可以获取字符串的长度。

比较字符串:可以使用==、!=、<、>、<=、>=等操作符进行字符串的比较。

查找和替换:string类提供了find()、rfind()、replace()等成员函数,用于在字符串中查找指定的子串并进行替换。

【https://cplusplus.com/reference/string/string/ 】

可以使用不同的构造函数(constructor)【注:C++中,构造函数是一种特殊的成员函数,它在创建类的对象时被自动调用。构造函数的主要目的是初始化对象的数据成员】来创建不同的字符串。这些是一些常见的方法示例:

☆默认构造函数(无参构造函数):例如:

string str; //创建一个空的string对象。

string str = "Hello World!"; //创建一个的string对象并赋值初始化

☆带字符串参数的构造函数:创建一个string对象,并将其初始化为一个给定的字符串。例如:

string str("Hello");

☆带字符参数和个数的构造函数:创建一个string对象,并将其初始化为指定个数的相同字符。例如:

string str(5, 'a');  // str = "aaaaa"

☆拷贝构造函数:使用一个已有的string对象创建一个新的string对象。例如:

string str1("Hello");

string str2(str1);  // str2 = "Hello"

下面介绍string 类中提供的 getline 函数。

getline()函数语法如下:

istream& getline (istream& is, string& str, char delim);

其中,is是输入流对象;str是目标字符串对象;delim是可选参数,表示定界符(分隔符,默认为换行符)。

使用getline()函数时,它会从输入流中读取一行文本,并将读取到的内容存储到目标字符串str中,直到遇到定界符(或文件结尾)为止。如果指定了定界符delim,则getline()函数会在遇到该字符时停止读取,否则默认为换行符。

#include <iostream>
#include <string>
using namespace std;

int main() {
  
    string str;
    cout << "请输入名字:";
    getline(cin, str);  //cin >> str;
    
     // 检查字符串是否为空
    if (str.empty()) {
        cout << "The string is empty." << endl;
    } else {
        cout << "The string is not empty." << endl;
    }
    
    return 0;
}

运行效果:

 特别说明:c++中,cin >> str 和 string类的getline(cin, str) 用来读取用户输入的两种不同方式的不同点:

数据类型不同:cin >> str是用来读取字符串类型的单个单词或数字型数据(整数、实数等),而getline(cin, str)则是用来读取整行的字符串。

分隔符:使用cin >> str时,输入被空白字符(如空格、制表符、换行符)分隔为不同的字符串,并将第一个非空白字符开始的连续字符序列存储到str中,剩余部分将会留在输入队列中;而getline(cin, str)则会读取整行输入,包括空白字符,在遇到换行符之前将其存储到str中。

输入限制:cin >> str只能读取到空白字符之前的内容,因此无法读取含有空格的字符串,一次只能读取一个单词或数字。而getline(cin, str)可以读取包含空格的完整行,因此可以读取多个单词或整行文本。

换行符处理:cin >> str读取后会将换行符留在输入流中,可以影响下一次读取操作。相比之下,getline(cin, str)会将换行符从输入流中移除,以防止影响后续读取操作。
【空白字符是指在文本中没有可见形式的字符,主要包括空格、制表符和换行符。它们在文本处理中具有不同的作用。

空格(Space):表示一个可见的空间,在文本中起到分隔单词或字符的作用。多个连续的空格会被视为一个空格。

制表符(Tab):通常用\t来表示,在文本中占据一个固定的宽度,经常用于对齐文本中的内容。

换行符(Newline):表示换行的特殊字符,在不同的操作系统中可能有不同的表示方式。在Unix和Linux系统中,换行符用\n表示;在Windows系统中,换行符由两个字符组成,即回车符(Carriage Return)和换行符,用\r\n表示。

这些空白字符在输入和输出操作中都需要注意处理。在C++中,空白字符通常用于分隔不同的数据项,而换行符用于标识一行的结束。了解和正确处理这些字符对于正确解析和处理用户输入以及生成正确格式的输出非常重要。】

2、演示了如何连接字符串、获取字符串长度、检查字符串是否为空、访问和修改字符串中的字符、查找子字符串的位置以及提取子字符串。您可以根据需要进一步使用std::string执行其他操作,例如插入、删除、比较等等。

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str1 = "Hello";
    string str2 = " world!";
    
    // 连接两个字符串
    string result = str1 + str2;
    cout << "Concatenated string: " << result << endl;
    
    // 获取字符串长度
    cout << "Length of the string: " << result.length() << endl;
    
    // 检查字符串是否为空
    if (result.empty()) {
        cout << "The string is empty." << endl;
    } else {
        cout << "The string is not empty." << endl;
    }
    
    // 访问字符串中的字符
    char c = result[0];
    cout << "First character of the string: " << c << endl;
    
    // 修改字符串中的字符
    result[0] = 'h';  // 将第一个字符修改为小写 'h'
    cout << "Modified string: " << result << endl;
    
    // 查找子字符串的位置
    size_t pos = result.find("world");
    if (pos != string::npos) {
        cout << "Substring 'world' found at position: " << pos << endl;
    } else {
        cout << "Substring not found." << endl;
    }
    
    // 提取子字符串
    string sub = result.substr(6, 5);  // 从位置 6 开始,提取长度为 5 的子字符串
    cout << "Substring: " << sub << endl;
    
    return 0;
}

你可以编译运行试试看。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1791376.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Pytorch】计算机视觉项目——卷积神经网络TinyVGG模型图像分类(如何使用自定义数据集)

目录 一、前言二、工作流程回顾三、详细步骤流程1. 环境配置2. 数据准备数据集下载数据存储结构&路径查看图片 3. 数据转换4. 自定义数据集&#xff08;Custom Dataset &#xff09;4.1 方法一&#xff1a;使用ImageFolder加载数据集信息查看张量转图片创建DataLoader 4.2 …

ChatGPT-4o抢先体验

速度很快&#xff0c;结果很智能&#xff0c;支持多模态输入输出&#xff0c;感兴趣联系作者

Unity开发Cosmos使用BNG Framework获取按键信息

Unity开发Cosmos使用BNG Framework获取按键信息 1、新建一个脚本&#xff0c;复制下面代码 using BNG;[Header("Input")]//[Tooltip("The key(s) to use to toggle locomotion type")]public List<ControllerBinding> locomotionToggleInput new …

SpringBoot+Vue实现前后端分离基本的环境搭建

目录 一、Vue项目的搭建 &#xff08;1&#xff09;基于vite创建vue项目 &#xff08;2&#xff09;引入elementplus &#xff08;3&#xff09;启动后端服务&#xff0c;并测试 二、SpringBoot项目的搭建 &#xff08;1&#xff09;通过idea创建SpringBoot项目 &#x…

每天五分钟深度学习PyTorch:Tensor张量的索引和切片

本文重点 有时候当我们拥有一个Tensor张量的时候,我们可能需要获取它某一维度的信息,那么此时我们就需要索引和切片的技术,它们可以帮助我们解决这些问题。 切片操作 a是四维的,然后默认是从第一维开始取,逗号表示取不同的维度 a[:2]表示第一维取0,1,后面三维取所有 …

一、大模型推理

https://github.com/hiyouga/LLaMA-Factory/blob/main/README_zh.md https://github.com/hiyouga/LLaMA-Factory/blob/main/examples/README_zh.md 安装 v7.1 https://github.com/hiyouga/LLaMA-Factory/releases/tag/v0.7.1 git clone --depth 1 https://github.com/hiyoug…

门面模式Api网关(SpringCloudGateway)

1. 前言 当前通过Eureka、Nacos解决了服务注册和服务发现问题&#xff0c;使用Spring Cloud LoadBalance解决了负载均衡的需求&#xff0c;同时借助OpenFeign实现了远程调用。然而&#xff0c;现有的微服务接口都直接对外暴露&#xff0c;容易被外部访问。为保障对外服务的安全…

问答机器人

怎样做自己的问答机器人&#xff1f; 根据我们提供的数据分析出问题的答案&#xff0c;我们并不需要训练自己的模型 微调模型 finetune&#xff0c;将语言模型调成另外的语言模型&#xff0c;更适合不同类型数据&#xff0c;运用finetune方法将模型变化 知识库模型 embedd…

alist配合onlyoffice 实现在线预览

alist配合onlyoffice 实现在线预览 文章目录 alist配合onlyoffice 实现在线预览一、安装onlyoffice二、增加view.html文件三、安装nginx&#xff0c;并增加conf配置文件四、alist预览配置增加 一、安装onlyoffice 我是采用docker安装&#xff0c;采用的版本是7.2&#xff0c; …

【因果推断python】16_工具变量2

目录 出生季度和教育对工资的影响 第一阶段 出生季度和教育对工资的影响 到目前为止&#xff0c;我们一直将这些工具视为一些神奇的变量 Z&#xff0c;它们具有仅通过干预变量影响结果的神奇特性。老实说&#xff0c;好的工具变量来之不易&#xff0c;我们不妨将它们视为奇迹…

Leetcode - 周赛400

目录 一&#xff0c;3168. 候诊室中的最少椅子数 二&#xff0c;3169. 无需开会的工作日 三&#xff0c;3170. 删除星号以后字典序最小的字符串 四&#xff0c;3171. 找到按位与最接近 K 的子数组 一&#xff0c;3168. 候诊室中的最少椅子数 本题是一道模拟题&#xff0c;直…

排序方法——《选择排序》

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;Yan. yan.                        …

HCIP-Datacom-ARST自选题库_10_多种协议多选【24道题】

1.如图所示&#xff0c;PE1和PE2之间通过LoopbackO接口建立MP-BGP邻居关系&#xff0c;在配完成之后&#xff0c;发现CE1和CE2之间无法互相学习路由&#xff0c;下列哪些选项会造成该问题的出现? PE1或PE2未在BGP-VPNV4单播地址族视图使能邻居A PE1或PE2上的VPN实例参数配置错…

htb_solarlab

端口扫描 80,445 子域名扫描 木有 尝试使用smbclient连接445端口 Documents目录可查看 将Documents底下的文件下载到本地看看 xlsx文件里有一大串用户信息&#xff0c;包括username和password 先弄下来 不知道在哪登录&#xff0c;也没有子域名&#xff0c;于是返回进行全端…

第N4周:中文文本分类

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、预备知识 中文文本分类和英文文本分类都是文本分类&#xff0c;为什么要单独拎出来个中文文本分类呢&#xff1f; 在自然语言处理&#xff08;NLP&#x…

SickOS1.1 - Shellshock原理和利用过程精讲

SickOS1.1的另一种思路&#xff1b;用另一种方法打透这台机器 Nikto扫描 正常都是-h扫描&#xff1b;有代理就用-useproxy 指向的代理ip:端口 nikto -h 192.168.218.157 -useproxy 192.168.218.157:3128apache版本&#xff0c;有点低&#xff0c;现在都是2.4.54版本了&#x…

PDF批量加水印 与 去除水印实践

本文主要目标是尝试去除水印&#xff0c;但是为了准备测试数据&#xff0c;我们需要先准备好有水印的pdf测试文件。 注意&#xff1a;本文的去水印只针对文字悬浮图片悬浮两种特殊情况&#xff0c;即使是这两种情况也不代表一定都可以去除水印。 文章目录 批量添加透明图片水印…

OpenStreetMap部署(OSM)

参考&#xff1a;https://github.com/openstreetmap/openstreetmap-website/blob/master/DOCKER.md OpenStreeMap 部署 操作系统建议使用 Ubuntu 22 版本 安装 Docker # 更新软件包索引&#xff1a; sudo apt-get update # 允许APT使用HTTPS&#xff1a; sudo apt-get inst…

TypeScript的never类型的妙用

never类型介绍 在 TypeScript 中&#xff0c;"never" 是一个表示永远不会发生的值类型。 使用场景 "never" 类型通常用于以下几种情况&#xff1a; 1、函数返回类型&#xff1a;当一个函数永远不会返回任何值&#xff08;比如抛出异常或者无限循环&…

使用 MDC 实现日志链路跟踪,包教包会!

在微服务环境中&#xff0c;我们经常使用 Skywalking、Spring Cloud Sleut 等去实现整体请求链路的追踪&#xff0c;但是这个整体运维成本高&#xff0c;架构复杂&#xff0c;本次我们来使用 MDC 通过 Log 来实现一个轻量级的会话事务跟踪功能&#xff0c;需要的朋友可以参考一…