string类(一)

string的定义方式

string类实现了多个构造函数的重载,常用的构造函数如下:

string();  //构造一个空字符串

string(const char* s);  //复制s所指的字符序列

string(const char* s, size_t n);  //复制s所指字符序列的前n个字符

string(size_t n, char c);  //生成n个c字符的字符串

string(const string& str);  //生成str的复制品

string(const string& str, size_t pos, size_t len = npos);  //复制str中从字符位置pos开始长度为len的字符

注意:其中npos 是一个静态成员常量值,对于 size_t 类型的元素具有最大可能值。当该值用作字符串成员函数中 len(或 sublen)参数的值时,表示“直到字符串末尾”。该常量定义为值 -1,因为 size_t 是无符号整数类型,所以它是该类型的最大可能表示值。

使用示例

 std::string s0 ("Initial string");

 std::string s1;
 std::string s4 ("A character sequence");
 std::string s5 ("Another character sequence", 12);
 std::string s6a (10, 'x');
 std::string s2 (s0);
 std::string s3 (s0, 8, 3);

string的插入

1.使用push_back进行插入

代码示例: 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s;
	s.push_back('h');
	s.push_back('e');
	s.push_back('l');
	s.push_back('l');
    s.push_back('o');
	cout << s << endl;  //hello
	return 0;
}

2、使用insert插入

//使用格式
//在pos位置插入一个string对象
string& insert (size_t pos, const string& str);
//在pos位置插入一个c类型字符串
string& insert (size_t pos, const char* s);
//在迭代器位置插入一个字符
iterator insert (iterator p, char c);

代码示例

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

int main()
{
    string str = "hello !";
	string str1 = "world";
	str.insert(6, str1);   //hello world!
    str.insert(12,"!!");   //hello world!!!
    str.insert(str.end(),'#');  //hello world!!!#
    return 0;
}

string的拼接

使用append完成string的拼接

//使用格式
string& append (const string& str);    //拼接一个string类对象
string& append (const char* s);    //拼接一个c类型字符串 
string& append (size_t n, char c);    //拼接n个字符

代码示例

#include <iostream>
#include <string>
using namespace std;
int main ()
{
    string str="hell";
    string str1="world";
    str.append("o ");
    str.append(str1);
    str.append(3,'!');
    
    std::cout << str << '\n';   //hello world!!!
    return 0;
}

string的删除

1.使用pop_back进行尾删

//使用格式
void pop_back();

示例代码如下

#include <iostream>
#include <string>
using namespace std;
int main ()
{
  string str ("hello world!");
  str.pop_back();
  cout << str << '\n';    //hello world
  return 0;
}

2.使用erase删除

//使用格式
string& erase (size_t pos = 0, size_t len = npos);	
iterator erase (iterator p);
iterator erase (iterator first, iterator last);

示例代码如下


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

int main ()
{
  //str中第一个字符用值0表示,而不是1
  string str ("This is an example sentence.");
  str.erase (10,8);
  str.erase (str.begin()+9);
  str.erase (str.begin()+5, str.end()-9);
  cout << str << endl;    //This sentence
  return 0;
}

string的查找

1.使用find函数正向搜索第一个匹配项

//使用规则
//find(string)正向搜索与string对象所匹配的第一个位置
size_t find (const string& str, size_t pos = 0) const;

//find(str)正向搜索与c类型字符串所匹配的第一个位置
size_t find (const char* s, size_t pos = 0) const;

//find(char)正向搜索与字符所匹配的第一个位置
size_t find (char c, size_t pos = 0) const;

示例代码

#include <iostream>
#include <string>
using namespace std;
int main()
{
    s1中第一个字符用0表示而不是1
	string s1("http://www.cplusplus.com/reference/string/string/find/");

	string s2("www");
	size_t pos1 = s1.find(s2);
	cout << pos1 << endl; //7

	char str[] = "cplusplus.com";
	size_t pos2 = s1.find(str);
	cout << pos2 << endl;  //11

	size_t pos3 = s1.find(':');
	cout << pos3 << endl; //4
	return 0;
}

2、使用rfind函数反向搜索第一个匹配项

//使用规则
//反向搜索与string对象所匹配的第一个位置
size_t rfind (const string& str, size_t pos = npos) const;

//反向搜索与c类型字符串所匹配的第一个位置
size_t rfind (const char* s, size_t pos = npos) const;

//反向搜索与字符所匹配的第一个位置
size_t rfind (char c, size_t pos = npos) const;

示例代码如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");

	string s2("string");
	size_t pos1 = s1.rfind(s2);
	cout << pos1 << endl; //42

	char str[] = "reference";
	size_t pos2 = s1.rfind(str);
	cout << pos2 << endl;  //25

	size_t pos3 = s1.rfind('/');
	cout << pos3 << endl; //53
	return 0;
}

string的比较

使用compare函数进行比较

//使用规则
int compare (const string& str) const;
int compare (size_t pos, size_t len, const string& str) const;
int compare (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) const;

比较规则: 

示例代码如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("hello world");
	string s2("hello byte");

	//"hello world"和"hello byte"比较
	cout << s1.compare(s2) << endl; //1

	//"ell"和"hello byte"比较
	cout << s1.compare(1, 3, s2) << endl; //-1

	//"hello"和"hello"比较
	cout << s1.compare(0, 4, s2, 0, 4) << endl; //0

	return 0;
}

string的替换

使用replace函数完成string的替换:

//使用规则
//将pos位置开始的len个字符替换为c类型字符串
string& replace (size_t pos, size_t len, const char* s);

//将pos位置开始的len个字符替换为n个字符char
string& replace (size_t pos, size_t len, size_t n, char c);

 代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");

	s.replace(6, 4, "byte"); //hello byted

	s.replace(10, 1, 2, '!'); //hello byte!!

	cout << s << endl;
	return 0;
}

string的交换

使用swap函数完成两个string类的交换:

//使用规则
void swap (string& str);
void swap(string& str1,string& str2);

代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("hello");
	string s2("world");
	
	s1.swap(s2);
	cout << s1 << endl; //world
	cout << s2 << endl; //hello

	swap(s1, s2);
	cout << s1 << endl; //hello
	cout << s2 << endl; //world
	return 0;
}

string的大小与容量

1、使用size函数或length函数获取当前有效字符的个数

//使用规则
size_t size() const;
size_t length() const

代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");
	cout << s.size() << endl; //11
	cout << s.length() << endl; //11
	return 0;
}

2、使用max_size函数获取string对象可以达到的最大长度

//使用规则
size_t max_size() const;

代码示例如下


#include <iostream>
#include <string>
using namespace std;
int main ()
{
    string str ("Test string");
    cout < str.max_size() << endl;    //4294967291
    return 0;
}

3、使用capacity函数获取当前对象所分配的存储空间的大小

//使用格式
size_t capacity() const;

示例代码如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");
	cout << s.capacity() << endl;    //15
	return 0;
}

4、使用resize改变当前对象的有效字符的个数

//使用规则
void resize (size_t n);
void resize (size_t n, char c);

将字符串大小调整为 n 个字符的长度。                                                                                   1.如果 n 小于当前字符串长度,则当前值将缩短为其前 n 个字符,并删除第 n 个之后的字符。                                                                                                                                         2.如果 n 大于当前字符串长度,则通过在末尾插入所需数量的字符来扩展当前内容,以达到 n 的大小。 如果指定了 c,则新元素将初始化为 c 的副本,否则,它们是值初始化字符('\0')。

代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("hello world");
	s1.resize(20);
	cout << s1.size() << endl; //20
	cout << s1.capacity() << endl; //31
	return 0;
}

n大于对象当前的size时,将size扩大到n,扩大的字符默认为'\0' 

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s2("hello world");
	s2.resize(20, 'x');
	cout << s2.size() << endl; //20
	cout << s2.capacity() << endl; //31
	return 0;
}

n大于对象当前的size时,将size扩大到n,扩大的字符为x。

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s3("hello world");
	s3.resize(5);
	cout << s3.size() << endl; //
	cout << s3.capacity() << endl; //
	return 0;
}

 n小于对象当前的size时,将size缩小到n。

注意:若给出的n大于对象当前的capacity,则capacity也会根据自己的增长规则进行扩大。

5、使用reserve改变当前对象的容量大小

//使用规则
void reserve (size_t n = 0);

代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");
	cout << s.size() << endl; //11
	cout << s.capacity() << endl; //15

	s.reserve(20); 
	cout << s.size() << endl; //11
	cout << s.capacity() << endl; //31
}

 1.如果 n 大于当前字符串容量,该函数会使容器将其容量增加到 n 个字符(或更大),size的值还是保持不变。

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s("hello world");
    cout << s.size() << endl; //11
	cout << s.capacity() << endl; //15

    s.reserve(2);
	cout << s.size() << endl; //11
	cout << s.capacity() << endl; //15
	return 0;
}

2.如果n小于当前字符串容量,则什么也不做,size的值还是保持不变。

6、使用clear删除对象的内容,删除后对象变为空字符串

//使用规则
void clear();

代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");

	s.clear();
	cout << s << endl;   //空字符串
	return 0;
}

7、使用empty判断对象是否为空

//使用规则
bool empty() const;

代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");
	cout << s.empty() << endl; //0

	s.clear();
	cout << s.empty() << endl; //1
	return 0;
}

string中元素的访问

1、使用‘[ ]’访问

因为string类对[ ]运算符进行了重载,所以我们可以直接使用[ ]+下标访问对象中的元素。并且该重载使用的是引用返回,所以我们可以通过[ ]+下标修改对应位置的元素。

//使用规则
char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

代码示例如下 

#include <iostream>
#include <string>
using namespace std;
int main ()
{
  string str ("Test string");
  for (int i=0; i<str.length(); ++i)
  {
     cout << str[i];
  }
  cout<<endl;    //Test string

  for (int i=0; i<str.length(); ++i)
  {
     str[i]='x';
  }
  cout<<str<<endl;    //xxxxxxxxxxx
  return 0;
}

2、使用at访问对象中的元素

因为at函数也是使用的引用返回,所以我们也可以通过at函数修改对应位置的元素。

//使用格式
char& at (size_t pos);
const char& at (size_t pos) const;

代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");
	for (size_t i = 0; i < s.size(); i++)
	{
		cout << s.at(i);
	}
	cout << endl;

	for (size_t i = 0; i < s.size(); i++)
	{
		s.at(i) = 'x';
	}
	cout << s << endl;
	return 0;
}

3、使用范围for访问对象中的元素

需要特别注意的是:若是需要通过范围for修改对象的元素,则用于接收元素的变量e的类型必须是引用类型,否则e只是对象元素的拷贝,对e的修改不会影响到对象的元素。

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");
	for (auto e : s)
	{
		cout << e;
	}
	cout << endl; //CSDN

	//使用范围for访问对象元素,并对其进行修改,则e必须是引用类型
	for (auto& e : s)
	{
		e = 'x';
	}
	cout << s << endl; //xxxx
	return 0;
}

4、使用迭代器访问对象中的元素

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");
	
    //auto iterator it1=s.begin();
	string::iterator it1 = s.begin();
	while (it1 != s.end())
	{
		cout << *it1;
		it1++;
	}
	cout << endl; //hello world

	//使用迭代器访问对象元素,并对其进行修改
	string::iterator it2 = s.begin();
	while (it2 != s.end())
	{
		*it2 += 1;
		it2++;
	}
	cout << s << endl; //ifmmp!xpsme
	return 0;
}

string中运算符的使用

1、operator=
string类中对=运算符进行了重载,重载后的=运算符支持string类的赋值、字符串的赋值以及字符的赋值。

示例代码如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1="hello world";
    cout<<s1<<endl;
}

2、operator+=
 string类中对+=运算符进行了重载,重载后的+=运算符支持string类的复合赋值、字符串的复合赋值以及字符复合的赋值。

代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("hello ");
	string s2("world");

	s1 += s2;
	cout << s1 << endl; //hello world

	s1 += "!!!";
	cout << s1 << endl; //hello world!!!

	return 0;
}

3、operator+
 string类中对+运算符进行了重载,重载后的+运算符支持以下几种类型的操作:

代码示例如下:

#include <iostream>
#include <string>
using namespace std;
main ()
{
  string firstlevel ("com");
  string secondlevel ("cplusplus");
  string scheme ("http://");
  string hostname;
  string url;

  hostname = "www." + secondlevel + '.' + firstlevel;
  url = scheme + hostname;

  std::cout << url << endl;    //http://www.cplusplus.com

  return 0;
}

4、operator>> 和 operator<<
 string类中也对>>和<<运算符进行了重载,从而我们可以直接使用>>和<<对string类进行输入和输出。

示例代码如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s;

    //输入
	cin >> s;

    //输出
	cout << s << endl;

	return 0;
}

其中我们必须注意输入的string类不能带空格,否则输入与输出就会不一致,至于为什么,我们后面会介绍。

5、relational operators
 string类中有一些被重载了的运算符,它们分别是==、!=、<、<=、>、>=。重载后的关系运算符支持string类和string类之间的关系比较、string类和字符串之间的关系比较、字符串和string类之间的关系比较。我们需要注意的是这些重载的运算符比较的是对应字符的ASCII码值

示例代码如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s1("hello world");
	string s2("hello byte");
	cout << (s1 > s2) << endl; //1
	cout << (s1 < s2) << endl; //0
	cout << (s1 == s2) << endl; //0
	return 0;
}

string中与迭代器相关的函数

1、与正向迭代器相关的函数
begin函数:返回一个指向字符串第一个字符的迭代器。

 iterator begin();
 const_iterator begin() const;

end函数:返回一个指向字符串结束字符的迭代器,即’\0’。

 iterator end();
 const_iterator end() const;

代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string str("Test string");
	string::iterator it = str.begin();
	while (it != str.end())
	{
		cout << *it;
		it++;
	}
	cout << endl;

	return 0;
}

2、与反向迭代器相关的函数
rbegin函数:返回指向字符串最后一个字符的反向迭代器

reverse_iterator rbegin();
const_reverse_iterator rbegin() const;

rend函数:返回指向字符串第一个字符前面的理论元素的反向迭代器。 

 reverse_iterator rend();
 const_reverse_iterator rend() const;

代码示例如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");

	string::reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit;
		rit++;
	}
	cout << endl; //dlrow olleh

	return 0;
}

string与字符串之间的转换

1、将字符串转换为string
 将字符串转换为string很简单,在前面讲string的定义方式时就有说到。

2、使用c_str或data将string转换为字符串

const char* c_str() const;
const char* data() const;

区别:

1.在C++98中,c_str()返回 const char* 类型,返回的字符串会以空字符结尾
2.在C++98中,data()返回 const char* 类型,返回的字符串不以空字符结尾
3.但是在C++11版本中,c_str()与data()用法相同。

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string s("hello world");
	const char* str1 = s.data();
	const char* str2 = s.c_str();

	cout << str1 << endl;
	cout << str2 << endl;
	return 0;
}

string中子字符串的提取

使用substr函数提取string中的子字符串

string substr (size_t pos = 0, size_t len = npos) const;

示例代码如下

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s1="hello world";
    string s2;

    s2=s1.substr(6,6);
    cout<<s2<<endl;    //world
    return 0;
}

string中的getline函数

我们知道,使用>>进行输入操作时,当>>读取到空格便会停止读取,因此我们将不能用>>将一串含有空格的字符串读入到string对象中。这时,我们就需要用getline函数完成一串含有空格的字符串的读取操作了。

//直到读取到换行符’\n’为止。
istream& getline (istream& is, string& str);
//直到读取到分隔符delim或换行符’\n’为止。
istream& getline (istream& is, string& str, char delim);

示例代码如下

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string s1;
    getline(cin,s1);  //输入:hello world
    cout<< s1 <<endl;  //输出:hello world

	string s2;
	getline(cin, s2, 'o'); //输入:hello world
	cout << s2 << endl; //输出:hello wo

	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值