【C++】string类(上):string类的常用接口介绍

文章目录

  • 前言
  • 一、C++中设计string类的意义
  • 二、string类的常用接口说明
    • [1. string类对象的常见构造](#1. string类对象的常见构造)
    • [2. string类对象的容量操作](#2. string类对象的容量操作)
      • [2.1 size、capacity 和 empty的使用](#2.1 size、capacity 和 empty的使用)
      • [2.2 clear的使用](#2.2 clear的使用)
      • [2.3 reserve的使用](#2.3 reserve的使用)
      • [2.4 resize的使用](#2.4 resize的使用)
    • [3. string类对象的访问及遍历操作](#3. string类对象的访问及遍历操作)
      • [3.1 下标[ ] 和 at](#3.1 下标[ ] 和 at)
      • [3.2 迭代器iterator](#3.2 迭代器iterator)
      • [3.3 范围for](#3.3 范围for)
    • [4. string类对象的修改操作](#4. string类对象的修改操作)
      • [4.1 push_back、append 和 operator+=(在字符串后追加字符)](#4.1 push_back、append 和 operator+=(在字符串后追加字符))
      • [4.2 insert(在字符串任意位置追加字符)](#4.2 insert(在字符串任意位置追加字符))
      • [4.3 erase(删除指定范围的字符)](#4.3 erase(删除指定范围的字符))
      • [4.3 replace(替换字符串中指定范围的字符)](#4.3 replace(替换字符串中指定范围的字符))
    • [5. string类对象的字符串操作](#5. string类对象的字符串操作)
      • [5.1 c_str的使用](#5.1 c_str的使用)
      • [5.2 find的使用](#5.2 find的使用)
      • [5.3 rfind的使用](#5.3 rfind的使用)
      • [5.4 substr(从字符串中提取一个子字符串)](#5.4 substr(从字符串中提取一个子字符串))
    • [6. string类非成员函数](#6. string类非成员函数)
      • [6.1 operator+](#6.1 operator+)
      • [6.2 relational operators系列函数](#6.2 relational operators系列函数)
      • [6.3 >>运算符重载 和 getline函数的区别](#6.3 >>运算符重载 和 getline函数的区别)

前言

一、C++中设计string类的意义
二、string类的常用接口说明(string类对象的常见构造、容量操作、遍历操作、修改操作和查找操作等接口,以及一些string类非成员函数的接口)


一、C++中设计string类的意义

C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中还提供了一些字符串操作库函数,但是这些库函数与字符串是分离开的,而且底层空间需要用户自己管理,操作繁琐且容易出错(如内存越界、忘记释放内存等)。
C++的string类封装了字符串的存储和操作,提供了更安全、便捷的接口。string类自动管理字符串的内存分配和释放,避免了手动管理内存的复杂性,减少了内存泄漏和悬空指针的风险;string类还提供了丰富的成员函数,如拼接、查找、替换、比较等,简化了字符串的常见操作;而且string类是类型安全的,避免了C语言中字符数组和指针的潜在问题,如类型不匹配或越界访问。

二、string类的常用接口说明

(string类的所有接口说明详见链接: link

1. string类对象的常见构造

C++11中,std::string类的构造函数的所有重载类型如下:

std::string类对象的常见构造介绍:

(constructor)函数名称 功能说明
string() 构造空的std::string类对象,即空字符串
string(const char* s) 用C-string来构造std::string类对象
string(size_t n, char c) 用n个c字符构造std::string类对象
string(const string& str) 拷贝构造函数
string (const string& str, size_t pos, size_t len = npos); 用str中字符串的pos位置往后的len个字符来构造初始化std::string类对象,如果len大于字符串pos位置往后的字符串长度,取到末尾也会停止

补充:npos是std::string类中的定义的public静态成员常量,它的数据类型是size_t
size_t 是一种无符号整数类型,当你将 -1 赋值给一个 size_t 类型的变量/常量时,会发生类型转换。由于 -1 是一个负数,而 size_t 是无符号类型(只能表示正数),因此 -1 会被转换为 size_t 类型的最大值。

cpp 复制代码
#include <string>
using namespace std;

int main()
{
	string s1; // 构造空的string类对象s1
	string s2("hello world"); // 用C格式字符串构造string类对象s2
	string s3(6, 'x'); // 用6个'x'字符构造string类对象s3
	string s4(s2); // 用对象s2拷贝构造s4
	string s5(s2, 5, 10); // 用s2中字符串pos位置往后的10个字符构造s5,
	                      // s2中字符串pos位置往后不够10个字符,取到其末尾停止
	return 0;
}

2. string类对象的容量操作

2.1 size、capacity 和 empty的使用

函数名称 功能说明
size(通用) 返回字符串有效字符长度(不包括'\0')
length(用法同size) 返回字符串有效字符长度
capacity 返回空间(容量)总大小(不包括'\0')
empty 检测字符串是否为空串,是返回true,否则返回false

补充:size()与length()方法底层实现原理完全相同,size()是后来添加的,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。

(1) size和capacity的使用

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1("wukong");
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;

	string s2("I love Minecraft");
	cout << "s2的有效字符长度:" << s2.size() << endl;
	cout << "s2的容量:" << s2.capacity() << endl;
	return 0;
}


(2)empty的使用

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1;
	cout << s1.empty() << endl;

	string s2("I love Minecraft");
	cout << s2.empty() << endl;
	return 0;
}

2.2 clear的使用

std::string 类提供的 clear() 成员函数,用于清除字符串中的所有字符,使字符串变为空字符串。这个方法不会改变字符串的容量,只是将字符串的长度设置为0。

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1("I love Minecraft");
	cout << "s1是否为空串:" << s1.empty() << endl;
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;

	s1.clear();

	cout << "s1是否为空串:" << s1.empty() << endl;
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;
	return 0;
}

2.3 reserve的使用

std::string 类提供的 reserve() 成员函数,用于请求字符串对象的容量调整。
注:这个函数不会改变字符串的有效字符长度,也不会修改字符串有效字符中的内容。


(1)使用 reserve() 扩容(vs2022运行结果):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1("wukong");
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;

	s1.reserve(50); // 将容量扩到50字节,但实际扩到了63字节,
	                // 这是由于内存对齐的一些规则导致的,但只会多扩,不会少扩 
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;
	return 0;
}

(2)使用 reserve() 缩容(vs2022不执行reserve函数的缩容命令):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1("wukong");
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;

	s1.reserve(10); 
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;

	s1.reserve(5);
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;
	return 0;
}

总结:
(1)扩容:如果请求的新容量大于当前容量,字符串会分配新的存储空间,使容量至少等于请求的新容量。
(2)缩容:如果请求的新容量小于当前容量,字符串的容量可能不会改变(因编译器而异)。

因为reserve函数的缩容机制因编译器而异,所以我们一般不会使用这个函数缩容。我们一般只用reserve函数进行扩容,使用场景如下:在你预先知道字符串将增长到某个大小时,可以使用reserve函数提前分配足够的空间,避免频繁扩容。

2.4 resize的使用


std::string 类提供的 resize() 成员函数,用于改变字符串的大小。
如果新的大小大于当前大小,字符串会用指定的字符填充(如果未指定填充字符,默认使用'\0'填充);如果新的大小小于当前大小,字符串会被截断。

(1)使用resize函数增加字符串大小:

cpp 复制代码
int main()
{
	string s1("wukong");
	cout << s1 << endl;
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;

	s1.resize(10,'x');
	cout << s1 << endl;
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;

	s1.resize(20,'x');
	cout << s1 << endl;
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;
	return 0;
}


(2)使用resize函数缩小字符串大小:

cpp 复制代码
int main()
{
	string s1("wukong");
	cout << s1 << endl;
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;

	s1.resize(4);
	cout << s1 << endl;
	cout << "s1的有效字符长度:" << s1.size() << endl;
	cout << "s1的容量:" << s1.capacity() << endl;
	return 0;
}

总结:
(1)增加大小:如果新的大小大于当前大小,字符串会用指定的字符填充。如果未指定填充字符,默认使用空字符('\0')填充。
(2)减少大小:如果新的大小小于当前大小,字符串会被截断,超出部分的字符会被丢弃。
(3)容量调整:resize 方法可能会改变字符串的容量。如果新的大小大于字符串的当前容量,就会扩容。

3. string类对象的访问及遍历操作

3.1 下标[ ] 和 at

函数名称 功能说明
operator[ ] 返回pos位置的字符(越界访问的情况是不确定的)
at 返回pos位置的字符(越界访问会抛异常)



(1) 使用下标[ ]访问及遍历std::string类对象中内容(调用operator[ ]函数,注意它两个版本的区别):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1("abcdef");
	for (size_t i = 0; i < s1.size(); ++i)
	{
		s1[i] += 1;
		cout << s1[i];
		// 普通对象调用 char& operator[](size_t pos); 
		// 返回字符串中指定位置字符的引用(char&),
		// 这意味着你可以通过返回的引用修改字符串中的字符。
	}
	cout << endl;

	const string s2("abcdef");
	for (size_t i = 0; i < s1.size(); ++i)
	{
		cout << s2[i];
		// const对象调用 const char& operator[](size_t pos) const; 
		// 返回字符串中指定位置字符的常引用(const char&),
		// 这意味着你只能读取字符串中的字符,而无法进行修改。
	}
	cout << endl;
	return 0;
}

(2)使用at访问及遍历std::string类对象中内容(调用at函数,它的使用跟operator[ ]函数类似):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1("abcdef");
	for (size_t i = 0; i < s1.size(); ++i)
	{
		s1[i] += 1;
		cout << s1.at(i);
	}
	cout << endl;

	const string s2("abcdef");
	for (size_t i = 0; i < s1.size(); ++i)
	{
		cout << s2.at(i);
	}
	cout << endl;
	return 0;
}

3.2 迭代器iterator

函数名称 功能说明
begin 获取字符串第一个字符的迭代器
end 获取字符串(不包括'\0')最后一个字符下一个位置的迭代器


cpp 复制代码
int main()
{
	string s1("abcdefgh");
	string::iterator it1 = s1.begin();
	// 普通对象调用 iterator begin();
	// 返回指向字符串第一个字符的普通迭代器,允许修改字符串中的字符。
	while (it1 != s1.end())
	{
		(*it1)++;
		cout << *it1;
		++it1;
	}
	cout << endl;

	const string s2("abcdefgh");
	string::const_iterator it2 = s2.begin();
	// const对象调用 const_iterator begin() const;
	// 返回指向字符串第一个字符的const迭代器,只允许读取字符串中的字符,不能修改。
	while (it2 != s2.end())
	{
		cout << *it2;
		++it2;
	}
	cout << endl;
	return 0;
}

为什么用 iterator(迭代器) 定义变量/对象时要指定类域?

要知晓原因需研究一下 iterator 的底层实现。

iterator 在底层的实现方式一般有以下两种:
(1)内部类实现: iterator(正向迭代器)是定义在string类中的内部类,内部类可以访问外部类的私有成员,从而实现高效的迭代器操作。定义内部类的对象时需要指定外部类类域。
(2)指针实现: 在一些简单的容器(如array,vector,string等)中,iterator可以直接通过指针实现。比如,在string类中,将 char* 类型重命名为 iterator,代码如下:typedef char* iterator。因为是在string类中将 char* 重命名为 iterator,所以在类外要使用string类中的 iterator类型定义变量时需要指定类域。

所以无论 iterator 在底层的实现方式是以上的哪一种,在使用 iterator(迭代器) 定义变量/对象时都需要指定类域。

3.3 范围for

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此

C++11中引入了基于范围的for循环。for循环后的括号由冒号" :"分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。

范围for的应用:
(1)范围for可以作用到数组和容器对象上进行遍历
(2)范围for的底层很简单,数组遍历实际就是使用指针(编译器会将范围for循环转换为基于指针的循环,使用数组的首地址和末地址来遍历数组中的元素);容器遍历实际就是替换为迭代器(范围for循环在容器中的底层实现是通过调用容器的begin()和end()方法来获取迭代器,并使用这些迭代器来遍历容器中的元素)

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	char array[] = "wukong";
	for (char e : array)
	{
		cout << e;
	}
	cout << endl;

	string str("one piece");
	for (char ch : str)
	{
		cout << ch;
	} 
	cout << endl;
	return 0;
}

4. string类对象的修改操作

4.1 push_back、append 和 operator+=(在字符串后追加字符)

函数名称 功能说明
push_back 在字符串后尾插字符
append 在字符串后追加一个字符串或字符序列
operator+= 在字符串后追加一个字符串或字符

(1)std::string类提供的push_back成员函数,用于将一个字符追加到字符串的末尾。

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1("wukong");
	cout << s1 << endl;
	
	s1.push_back('o');
	cout << s1 << endl;

	s1.push_back('n');
	cout << s1 << endl;
	
	s1.push_back('e');
	cout << s1 << endl;
	return 0;
}


(2)std::string类提供的append成员函数(运算符重载),用于将一个字符串或字符序列追加到当前字符串的末尾。

示例一(追加另一个字符串的一部分到当前字符串的末尾):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1("zhangsan");
	cout << s1 << endl;
	
	string s2("i love you");
	s1.append(s2, 1, 5);
	// 调用 string& append(const string& str, size_t subpos, size_t sublen);
	// 用于将另一个字符串的一部分(从subpos位置往后sublen个字符)追加到当前字符串的末尾。
	// subpos位置往后的字符个数不够sublen,到末尾也会停止,不会额外追加。
	cout << s1 << endl;
	
	string s3("i like apple");
	s1.append(s3, 6, 20);
	cout << s1 << endl;
	return 0;
}


示例二(追加字符数组的前n个字符到当前字符串的末尾):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1("one piece ");
	cout << s1 << endl;
	
	char a1[] = "is still enough";
	s1.append(a1, 9);
	// 调用 string& append(const char* s, size_t n);
	// 用于将字符数组的前n个字符追加到当前字符串的末尾。
	cout << s1 << endl;
	
	char a2[] = "missing is silent";
	s1.append(a2, 7);
	cout << s1 << endl;
	return 0;
}

(3)std::string类提供的operator+=成员函数,用于将一个字符串、字符数组或单个字符追加到当前字符串的末尾。

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string s1("One Piece ");
	cout << s1 << endl;
	
	string s2("is a ");
	s1 += s2;
	cout << s1 << endl;

	char a1[] = "Miracle";
	s1 += a1;
	cout << s1 << endl;
	
	s1 += '!';
	cout << s1 << endl;
	return 0;
}

4.2 insert(在字符串任意位置追加字符)

std::string类提供的insert成员函数,用于在字符串的指定位置插入新的字符或子串。

示例一(在指定位置插入另一个字符串的子串):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string str1 = "i one piece!";
	string str2 = "peace and love";
	str1.insert(1, str2, 9, 20);
	// 调用string& insert(size_t pos, const string& str, size_t subpos, size_t sublen);
	// 参数:
	// pos:插入的位置。
	// str:要插入的std::string对象。
	// subpos:从str中开始插入的位置。
	// sublen:要插入的字符数。
	cout << str1 << endl;
	return 0;
}

示例二(在指定位置插入C风格字符串的前n个字符):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string str1 = "war and !";
	char ch[] = "peace and love";
	str1.insert(8, ch, 5);
	// 调用string& insert (size_t pos, const char* s, size_t n);
	// 在指定位置插入C风格字符串的前n个字符。
	cout << str1 << endl;
	return 0;
}


示例三(在指定位置插入n个字符):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string str1 = "hello";
	str1.insert(2, 5, 'x');
	// 调用string& insert (size_t pos, size_t n, char c);
	// 在指定位置插入n个c字符。
	cout << str1 << endl;
	return 0;
}

4.3 erase(删除指定范围的字符)

std::string类提供的erase成员函数,用于从字符串中删除指定范围的字符。

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string str1 = "hello world!";
	str1.erase(6, 5);
	// 调用string& erase (size_t pos = 0, size_t len = npos);
	// 参数:
    // pos:开始删除的位置。
    // n:要删除的字符数。
	cout << str1 << endl;
	return 0;
}

4.3 replace(替换字符串中指定范围的字符)

std::string类提供的replace成员函数,用于替换字符串中指定范围的字符。

示例一(将字符串中指定范围的字符替换成另一个字符串的子串):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string str1 = "xxx xxxxxxxxxx xxx";
	string str2 = "one two three";
	str1.replace(4, 10, str2, 8, 10);
	// 调用string& replace (size_t pos,  size_t len,  const string& str,
    //                      size_t subpos, size_t sublen);
	// 参数:
    // pos:开始替换的位置。
    // n:要替换的字符数。
    // str:用于替换的std::string对象。
    // subpos:在str中用于替换的起始位置。
    // sublen:用于替换的字符长度
	cout << str1 << endl;
	return 0;
}


示例二(将字符串中指定范围的字符替换成C风格字符串的前n个字符):

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string str1 = "xxx xxxxxxxxxx xxx";
	char ch[] = "one two three";
	str1.replace(4, 10, ch, 3);
	// 调用string& replace (size_t pos,  size_t len,  const char* s, size_t n);
	// 将字符串中指定范围的字符替换成C风格字符串的前n个字符
	cout << str1 << endl;
	return 0;
}


示例三(将字符串中指定范围的字符替换成n个c字符):

cpp 复制代码
int main()
{
	string str1 = "xxx xxxxxxxxxx xxx";
	str1.replace(4, 10, 5, 'o');
	// 调用	string& replace (size_t pos,  size_t len,  size_t n, char c);
	// 将字符串中指定范围的字符替换成n个c字符
	cout << str1 << endl;
	return 0;
}

5. string类对象的字符串操作

5.1 c_str的使用

std::string类提供的 c_str 成员函数,返回 C 格式字符串。
这个函数在需要将 std::string 对象传递给需要 C 格式字符串的函数时非常有用。

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
	string str("Please split this sentence into tokens");
	char* cstr = new char[str.size() + 1];
	strcpy(cstr, str.c_str());
    // char* strcpy(char* destination, const char* source );

	cout << cstr << endl;
	delete[] cstr;
	return 0;
}

5.2 find的使用

std::string类提供的 find 成员函数,从字符串pos位置开始往后找指定的字符或子串,找到了返回字符或子串首次出现的位置。如果未找到字符或子串,则返回一个特殊的常量 std::string::npos,表示"未找到"。

示例一(从字符串pos位置开始往后找指定的字符串):

cpp 复制代码
int main()
{
    string s1 = "Hello World!";
    string s2 = "World";
    size_t pos = s1.find(s2);
    // pos不指定默认为0
    cout << pos << endl;
    return 0;
}


示例二(从字符串pos位置开始往后找指定的C风格字符串):

cpp 复制代码
int main()
{
    string s1 = "Hello World!";
    size_t pos = s1.find("llo");
    cout << pos << endl;
    return 0;
}


示例三(从字符串pos位置开始往后找指定的字符):

cpp 复制代码
int main()
{
    string s1 = "war and peace";
    size_t pos = s1.find(' ');
    while (pos != string::npos)
    {
        s1[pos] = 'X';
        pos = s1.find(' ', pos + 1);
    }
    cout << s1 << endl;
    return 0;
}

5.3 rfind的使用

std::string 类中的 rfind 成员函数,用于在字符串中从后向前查找指定的字符或子串,找到了返回字符或子串最后一次出现的位置。如果未找到字符或子串,则返回一个特殊的常量 std::string::npos,表示"未找到"。

cpp 复制代码
int main()
{
    string s1 = "war war war war";
    size_t pos = s1.rfind("war");
    cout << pos << endl;
    return 0;
}

5.4 substr(从字符串中提取一个子字符串)

std::string 类中的 substr 成员函数,用于从字符串中提取一个子字符串,通过指定起始位置和长度来获取子字符串。

cpp 复制代码
#include <string>
#include <iostream>
using namespace std;
int main()
{
    string s1 = "Hello World!";
    string s2 = s1.substr(6, 5);
    cout << s2 << endl;
    return 0;
}

6. string类非成员函数

函数名称 功能说明
operator+ 尽量少用,因为传值返回,导致深拷贝效率低
operator>> 输入运算符重载
operator<< 输出运算符重载
getline 获取一行字符串
relational operators 大小比较

6.1 operator+

std::string 类提供了多种方式来连接字符串,其中 operator+ 是一个常用的非成员函数,operator+ 的非成员函数形式允许你将两个字符串连接起来,或者将字符串与其他类型的对象(如C风格字符串、字符等)连接起来。

示例中依次调用以上operator+ 非成员函数的5种重载形式:

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
int main() {
    std::string str1 = "Hello, ";
    std::string str2 = "world!";
    const char* cstr = "C-style string";
    char ch = '!';

    // 连接两个 string类对象
    string result1 = str1 + str2;

    // 连接 string类对象 和 C风格字符串
    string result2 = str1 + cstr;

    // 连接 C风格字符串 和 string类对象
    string result3 = cstr + str1;

    // 连接 string对象 和 字符
    string result4 = str1 + ch;

    // 连接 字符 和 string对象
    string result5 = ch + str1;

    cout << result1 << endl;
    cout << result2 << endl;
    cout << result3 << endl;
    cout << result4 << endl;
    cout << result5 << endl;
    return 0;
}

6.2 relational operators系列函数

std::string 类提供了一系列非成员函数形式的关系运算符的重载(Relational Operators),用于比较两个字符串 或 字符串与C风格字符串。
这些运算符包括:==(等于)、!=(不等于)、<(小于)、<=(小于等于)、>(大于)和 >=(大于等于)。

cpp 复制代码
int main() {
    std::string str1 = "apple";
    std::string str2 = "banana";
    const char* cstr = "apple";
  
    // 比较两个 std::string 对象
    cout << "str1 == str2: " << (str1 == str2) << endl; 
    cout << "str1 != str2: " << (str1 != str2) << endl; 
    cout << "str1 < str2: " << (str1 < str2) << endl;  

    // 比较 std::string 和 C风格字符串
    cout << "str1 == cstr: " << (str1 == cstr) << endl; 
    cout << "str1 != cstr: " << (str1 != cstr) << endl; 
    cout << "str1 < cstr: " << (str1 < cstr) << endl;
   
    // 比较 C风格字符串 和 std::string
    cout << "cstr == str2: " << (cstr == str2) << endl;    
    cout << "cstr != str2: " << (cstr != str2) << endl;
    cout << "cstr < str2: " << (cstr < str2) << endl;    
    return 0;
}

6.3 >>运算符重载 和 getline函数的区别

(1) >>运算符重载
>>是流提取运算符,通常用于从输入流(如 std::cin)中读取数据。

行为:
读取数据时,会跳过前导空白字符(如空格、制表符、换行符等)。
读取到第一个空白字符时停止,空白字符不会被包含在结果中。
适用于读取单个单词或简单数据类型(如 int、double、std::string 等)。

示例:

cpp 复制代码
int main()
{
	string word;
	cin >> word;// 输入"   hello world"
	            // >>运算符重载读取数据时,会跳过前导空白字符;
				// 开始读取有效字符时,读取到第一个空白字符时停止,空白字符不会被包含在结果中。
	            // 所以 word 的值为"hello"
	cout << "输出:" << word << endl;
	return 0;
}


(2) getline 函数
getline 是专门用于从输入流中读取一行数据的函数。

行为:
读取整行内容,直到遇到指定的分隔符(默认为换行符 \n)。
不会跳过前导空白字符,会读取包括空格在内的所有字符。
读取的内容包含分隔符之前的所有字符,但不包括分隔符本身。

示例一(分隔符默认为换行符 \n):

cpp 复制代码
int main()
{
	string word;
	getline(cin, word);// 输入 "   hello world"
	            // getline函数读取数据时,不会跳过前导空白字符,
				// 一直读取内容直到遇到指定的分隔符(默认为换行符 \n),
	            // 所以 word 的值为 "   hello world"
	cout << "输出:" << word << endl;
	return 0;
}


示例二(自己指定的分隔符):

cpp 复制代码
int main()
{
	string word;
	getline(cin, word, '+');// 输入 "   hello world/ncrazy 6+1"
	            // getline函数读取数据时,会一直读取到到指定的分隔符'+'才停止
	            // 所以 word 的值为 "   hello world/ncrazy 6"
	cout << "输出:" << word << endl;
	return 0;
}

相关推荐
小鹿撞出了脑震荡3 分钟前
Effective Objective-C 2.0 读书笔记——类对象
开发语言·ios·objective-c
shy^-^cky1 小时前
Go学习:Go语言中if、switch、for语句与其他编程语言中相应语句的格式区别
开发语言·学习·go语言
csucoderlee1 小时前
Go语言中结构体字面量
开发语言·后端·golang
OpenC++1 小时前
【C++】线程池实现
开发语言·c++·经验分享·算法·leetcode·设计模式
股票数据接口1 小时前
2025年度Python最新整理的免费股票数据API接口
开发语言·python·fastapi
飞yu流星6 小时前
c++ stl 遍历算法和查找算法
开发语言·c++·算法
苦瓜汤补钙7 小时前
(二)QT——按钮小程序
开发语言·c++·qt·小程序
Victoria.a8 小时前
list容器(详解)
数据结构·c++·list
SomeB1oody9 小时前
【Rust自学】18.1. 能用到模式(匹配)的地方
开发语言·后端·rust