当前位置: 首页 > article >正文

【c++语言程序设计】字符串与浅层复制(深拷贝与浅拷贝)

字符串常量是用一对双引号括起来的字符序列,例如,"abcd" " China"" This is a string." 都是字符串常量。它在内存中的存放形式是,按串中字符的排列次序顺序存放,每个字符占1字节,并在末尾添加'\0'作为结尾标记

字符串常量指针

这实际上是一个隐含创建的类型为 char的数组,一个字符串常量就表示这样一个数组的首地址。

const char *STRING1 = "This is a string.";

它是一个常量字符串,无法通过 STRING1 修改字符串内容

字符数组

字符串变量也可以用类似方式来表示。如果创建一个 char数组,每个元素存放字符串的一个字符,在末尾放置一个'\0',便构成了C++字符串。

在定义用于存放字符串的字符数组时,数组长度应至少为字符串字符数加1(用于存储结尾的 '\0'

char str[8] = {'p', 'r', 'o', 'g', 'r', 'a', 'm', '\0'};
char str[8] = "program";
char str[] = "program";

它的存储方式与字符串常量无异,但由于它是程序员创建的数组,因此可以改写其内容,因而这就是字符串变量而非常量

  • 数组大小:定义字符数组的长度时,大小应至少为字符串长度加1。
  • '\0' 结尾:字符串结尾 '\0' 是必须的,否则字符串操作函数(如 strlenstrcpy 等)无法正确判断字符串结束。
  • 字符串可修改:字符数组 str 是变量,可以直接修改其内容,而字符串常量不允许这样操作。

 尽管对用字符数组表示的字符串进行初始化还比较容易、直观,但进行许多其他字符串操作时却比较麻烦。执行很多字符串操作需要借助 cstring头文件中的字符串处理函数,例如将一个字符串的内容复制到另一个字符串需要用 strepy函数,按辞典顺序比较两个的大小需要用 strcmp函数,将两个字符串连接起来需要用 strcat函数。另外,当字符串长度很不确定时,需要用 new 动态创建字符数组,最后还要用 delete释放,这些都相当烦琐。

string

数组数据与处理数据的函数分离也不符合面向对象方法的要求。

C++标准类库将面向对象的串的概念加入到C++语言中,预定义了字符串类( string类),string类提供了对字符串进行处理所需要的操作。使用 string类需要包含头文件 string。string类封装了串的属性并提供了一系列允许访问这些属性的函数。

string类的构造函数

  • string():默认构造函数,创建一个长度为0的字符串。

  • string(const string& rhs):复制构造函数,用已有的string对象初始化新的string对象。

  • string(const char* s):使用指向字符串常量的指针*s初始化string对象。

  • string(const string& rhs, unsigned int pos, unsigned int n):从rhs对象的pos位置开始提取n个字符,用它们初始化新的string对象。

  • string(const char* s, unsigned int n):使用指针s所指字符串的前n个字符初始化string对象。

  • string(unsigned int n, char c):将字符c重复n次,用于初始化string对象

由于string类接收const char*类型的构造函数,字符串常量和字符数组都可以隐式转换为string对象。

string str = "Hello world!";

string类的操作符

string类重载了许多操作符,支持赋值、连接、比较等功能

操作符

示例

功能说明

+

s + t

将字符串s和t连接成新串

=

s = t

用t更新s

+=

s += t

等价于s = s + t

==

s == t

判断s和t是否相等

!=

s != t

判断s和t是否不等

<

s < t

判断s是否小于t(字典顺序)

<=

s <= t

判断s是否小于或等于t

>

s > t

判断s是否大于t

>=

s >= t

判断s是否大于或等于t

[ ]

s[i]

访问字符串s中下标i的字符

字符串的大小比较是按字典顺序进行,遵循以下规则:

  1. 如果两串长度和内容都相同,则==
  2. 如果第一个不相同字符的ASCII码较小,则对应的字符串较小。
  3. 如果一串是另一串的前缀,则前缀串较小。

常用成员函数

以下是一些string类的常用成员函数:

  • 追加string append(const char* s):将字符串s追加到本串尾部。

  • 赋值string assign(const char* s):将s赋值给本对象。

  • 比较int compare(const string& str) const:比较本字符串和str的大小。

  • 插入string& insert(unsigned int p0, const char* s):将s插入到本串的p0位置前。

  • 取子串string substr(unsigned int pos, unsigned int n) const:返回从pos位置开始的n个字符的子串。

  • 查找unsigned int find(const basic_string& str) const:查找并返回str第一次在本串中出现的位置。

  • 获取长度unsigned int length() const:返回字符串的长度(字符个数)。

  • 交换void swap(string& str):交换本字符串和str的内容。

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

// 根据 value 的值输出 true 或 false,title 为提示文字
inline void test(const char *title, bool value) {
    cout << title << " returns " << (value ? "true" : "false") << endl;
}

int main() {
    string s1 = "DEF";
    cout << "s1 is " << s1 << endl;
    
    string s2;
    cout << "Please enter s2: ";
    cin >> s2;  // 输入字符串 s2
    cout << "length of s2: " << s2.length() << endl;  // 输出 s2 的长度

    // 比较运算符的测试
    test("s1 <= \"ABC\"", s1 <= "ABC");     // 判断 s1 是否小于等于 "ABC"
    test("\"DEF\" <= s1", "DEF" <= s1);     // 判断 "DEF" 是否小于等于 s1

    // 连接运算符的测试
    s2 += s1;  // 将 s1 连接到 s2 的末尾
    cout << "s2 = s2 + s1: " << s2 << endl;
    cout << "length of s2: " << s2.length() << endl;  // 输出连接后的 s2 的长度

    return 0;
}

getline函数 

getline函数是用于从输入流中读取字符串的函数,在C++中,常用于从cin或文件中获取一行字符串。

  • getline不会忽略开头的空白字符(空格、制表符等),直接将其作为内容的一部分。

  • getline读取结束后,分隔符本身不会包含在字符串中,但会从输入流中移除

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

int main() {
    for (int i = 0; i < 2; i++) {
        string city, state;
        
        // 以逗号为分隔符读取城市名称
        getline(cin, city, ',');
        
        // 读取国家/地区名称,直到行尾
        getline(cin, state);
        
        cout << "City: " << city << " State: " << state << endl;
    }
    return 0;
}

使用场景

  • 读取整行文本:适用于读取包含空格的完整句子,如从用户输入中获取一行完整文本。

  • 自定义分隔:适合处理结构化文本输入,指定分隔符来分割输入内容,例如CSV文件的逐行读取


http://www.kler.cn/a/382586.html

相关文章:

  • C# 内存管理与对象生命周期在面向对象设计中的重要性
  • 数据库->索引
  • 【google play】使用Java接入谷歌支付流程
  • 【Wi-Fi】802.11ac wave1 vs 802.11ac wave2
  • 零基础‘自外网到内网’渗透过程详细记录(cc123靶场)——下
  • 高效集成金蝶云星空销售出库单的解决方案
  • 《高等学校化学学报》
  • python 语法
  • 《质谱学报》
  • C++类和对象上
  • wps的Excel中使用条件格式
  • BM25:最佳匹配 ,文本相关性评分算法
  • 机器学习—代码中的推理
  • 【RabbitMQ】03-交换机
  • vue 快速入门
  • cv::Mat初始化、赋值初始化与访问方式
  • 野火PID调试助手由HAL库移植到标准库
  • 蓝桥杯第21场小白入门赛补题
  • FastDDS服务发现之PDP的收发
  • 【线程与并发】详谈 可见性,有序问题
  • Spring Boot 与 Vue 共筑畅销图书推荐卓越平台
  • C#-类:静态成员的介绍
  • LaTeX中的\pdfoutput命令:输出PDF
  • android 使用xml设置背景图片和圆角
  • 新兴好用办公软件,协作效率翻倍就用它了!ONLYOFFICE最近发布了文档8.2版本
  • 猫用宠物空气净化器推荐,希喂,美的哪款除毛好、噪音小?