编译环境

系统环境:

patten@patten-hp:~$ sudo lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 16.04.6 LTS
Release:	16.04
Codename:	xenial
patten@patten-hp:~$

IDE环境:Visual Studio Code,Version: 1.36.1

string常用函数汇总

append()

常用函数原型

  basic_string &append( const basic_string &str );  //在字符串的末尾添加str
  
  basic_string &append( const char *str );  //在字符串的末尾添加str
  
  basic_string &append( const basic_string &str, size_type index, size_type len );  //在字符串的末尾添加str的子串,子串以index索引开始,长度为len
  
  basic_string &append( const char *str, size_type num );  //在字符串的末尾添加str中的num个字符
  
  basic_string &append( size_type num, char ch ); //在字符串的末尾添加num个字符ch,当num=1时,相当于push_back(char ch)
  
  basic_string &append( input_iterator start, input_iterator end );  //在字符串的末尾添加以迭代器start和end表示的字符序列

常用函数功能

  • 直接添加另一个完整的字符串:如str1.append(str2);
  • 添加另一个字符串的某一段子串:如str1.append(str2, 11, 7);
  • 添加几个相同的字符:如str1.append(5, ‘.’);注意,个数在前字符在后.上面的代码意思为在str1后面添加5个"."

使用示例

//main.cpp
#include <iostream>
using namespace std;
//========================================
int main()

{
  string str1 = "I like C++";
  string str2 = ",I like the world.";
  string str3 = "Hello";
  string str4("Hi");
  //====================================
  str1.append(str2);
  str3.append(str2, 11, 7);
  str4.append(5, '.');
  //====================================
  cout << str1 << endl;
  cout << str3 << endl;
  cout << str4 << endl;
  getchar();

  return 0;
}

编译输出

patten@patten-hp:~/workspace/others/cpp/demo$ g++ main.cpp -std=c++11
patten@patten-hp:~/workspace/others/cpp/demo$ ./a.out 
I like C++,I like the world.
Hello world.
Hi.....

patten@patten-hp:~/workspace/others/cpp/demo$

push_back()

函数原型

void push_back(
    value_type _Ch
);

函数功能

将字符添加到字符串的末尾,注意是字符而不是字符串。相当于basic_string &append( size_type num, char ch );,其中num=1。

使用示例

my_str.push_back("123");//错误
my_str.push_back('1');//ok

sprintf()

函数原型

int sprintf( char *buffer, const char *format [, argument] ... );

函数功能

除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:格式化字符串上。 printfsprintf都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的格式说明符(format specifications) 来占据一个位置,在后边的变参列表中提供相应的变量,最终函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要 的字符串。

使用示例

//main.cpp

#include <stdio.h>
#include <iostream>

int main() {
  char buffer[200], s[] = "computer", c = 'l';
  int i = 35, j;
  float fp = 1.7320534f;                            // Format and print various data:
  j = sprintf(buffer, "String: %s \n", s);          // C4996
  j += sprintf(buffer + j, " Character: %c \n", c);  // C4996
  j += sprintf(buffer + j, " Integer: %d \n", i);    // C4996
  j += sprintf(buffer + j, " Real: %f \n", fp);      // C4996
  // Note: sprintf is deprecated; consider using sprintf_s instead
  printf("Output:\n %s \ncharacter count = %d \n", buffer, j);
  return 0;
}

编译输出

patten@patten-hp:~/workspace/others/cpp/demo$ g++ main.cpp -std=c++11
patten@patten-hp:~/workspace/others/cpp/demo$ ./a.out 
Output:
 String: computer 
 Character: l 
 Integer: 35 
 Real: 1.732053 
 
character count = 64 
patten@patten-hp:~/workspace/others/cpp/demo$

insert()

函数原型

basic_string& insert( size_type index, size_type count, CharT ch );  //在index位置插入count个字符ch

basic_string& insert( size_type index, const CharT* s ); //index位置插入一个常量字符串

basic_string& insert( size_type index, const CharT* s, size_type count );  //index位置插入常量字符串中的count个字符

basic_string& insert( size_type index, const basic_string& str );  //index位置插入常量string

basic_string& insert( size_type index, const basic_string& str, size_type index_str, size_type count );  //index位置插入常量str的从index_str开始的count个字符

basic_string& insert( size_type index, const basic_string& str, size_type index_str, size_type count = npos);  //index位置插入常量str从index_str开始的count个字符,count可以表示的最大值为npos.这个函数不构成重载  npos表示一个常数,表示size_t的最大值,string的find函数如果未找到指定字符,返回的就是一个npos

使用示例

//main.cpp

// inserting into a string
#include <iostream>
#include <string>

int main() {
  std::string str = "to be question";
  std::string str2 = "the ";
  std::string str3 = "or not to be";
  std::string::iterator it;

  // used in the same order as described above:
  str.insert(6, str2);                    // to be (the )question
  str.insert(6, str3, 3, 4);              // to be (not )the question
  str.insert(10, "that is cool", 8);      // to be not (that is )the question
  str.insert(10, "to be ");               // to be not (to be )that is the question
  str.insert(15, 1, ':');                 // to be not to be(:) that is the question
  it = str.insert(str.begin() + 5, ',');  // to be(,) not to be: that is the question
  str.insert(str.end(), 3, '.');          // to be, not to be: that is the question(...)
  str.insert(it + 2, str3.begin(), str3.begin() + 3);  // (or )

  std::cout << str << '\n';
  return 0;
}

编译输出

patten@patten-hp:~/workspace/others/cpp/demo$ g++ main.cpp -std=c++11
patten@patten-hp:~/workspace/others/cpp/demo$ ./a.out 
to be, or not to be: that is the question...
patten@patten-hp:~/workspace/others/cpp/demo$

length()/size()

两个不同名字为什么放在一起呢?因为,**两者几乎没有任何区别。**微小区别就是:

  • size() 一般用作返回容器大小的方法;
  • length() 一般用作返回一个序列的长度。

总之,length是因为沿用C语言的习惯而保留下来的,string类最初只有length,引入STL之后,为了兼容又加入了size,它是作为STL容器的属性存在的,便于符合STL的接口规则,以便用于STL的算法。

需要注意的是:string类的length()或者size()函数返回的是unsigned integer(无符号数)类型。而用在for循环时,正常不会出错,但作为判断条件时,当s.length()等于0时,s.length()-1不等于 -1

使用示例

string strTest="test";
strTest.length();			//结果为4
strTest.size();				//结果为4

reserve()

函数原型

#include <string>
 void reserve( size_type size = 0 );

函数功能

函数reserve()将字符串的容量设置为至少size. 如果size指定的数值要小于当前字符串中的字符数(亦即size < this→size()), 容量将被设置为可以恰好容纳字符的数值. reserve()以线性时间(linear time)运行。

reserve为容器预留足够的空间,避免不必要的重复分配,分配空间大于等于函数的参数,影响capacity

它最大的用处是为了避免反复重新分配缓冲区内存而导致效率降低,或者在使用某些STL操作(例如std::copy)之前保证缓冲区够大。

capacity()

函数原型

#include <string>
 size_type capacity() const;

函数功能

函数capacity()返回string预先保留的最大元素数量. 例如, 下面的代码使用两个不同的方法设置两个vector的容量. 一个方法传递一个实参给构造函数为初始化的尺寸提供建议, 另外一个方法调用reserve函数达到类似的目的。如果string长度变长,capacity()变化值步长为初始string.size()的整倍数。比如:

string s = "Patten"; //"Patten"此时s.size()=6;s.capacity()=6
s.insert(1, " test1 ")  //"P test atten"此时s.size()=13;s.capacity()=18

使用示例

//main.cpp

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

int main() {
  string s1("Junmatek");
  cout << "The capacity of s1 is " << s1.capacity() << endl;
  string s2;
  s2.reserve(20);
  cout << "The capacity of s2 is " << s2.capacity() << endl;

  return 0;
}

编译输出

patten@patten-hp:~/workspace/others/cpp/demo$ g++ main.cpp -std=c++11
patten@patten-hp:~/workspace/others/cpp/demo$ ./a.out 
The capacity of s1 is 15
The capacity of s2 is 30
patten@patten-hp:~/workspace/others/cpp/demo$

resize()

函数原型

void resize (size_t n);  //设置str的size为n
void resize (size_t n, char c);  //设置str的size为n,不足的末尾补字符c

函数功能

resize调整容器中有效数据区域的尺寸,如果尺寸变小,原来数据多余的截掉。若尺寸变大,不够的数据用该函数第二个参数填充,影响size

resize(),设置大小(size);
reserve(),设置容量(capacity);
size()是分配容器的内存大小,而capacity()只是设置容器容量大小,但并没有真正分配内存。
打个比方:正在建造的一辆公交车,车里面可以设置40个座椅(reserve(40);),这是它的容量,但并不是说它里面就有了40个座椅,只能说明这部车内部空间大小可以放得下40张座椅而已。而车里面安装了40个座椅(resize(40);),这个时候车里面才真正有了40个座椅,这些座椅就可以使用了

使用示例

// resizing string
#include <iostream>
#include <string>

int main ()
{
  std::string str ("I like to code in C");
  std::cout << str << '\n';

  unsigned sz = str.size();

  str.resize (sz+2,'+');
  std::cout << str << '\n';

  str.resize (14);
  std::cout << str << '\n';
  return 0;
}

编译输出

patten@patten-hp:~/workspace/others/cpp/demo$ g++ main.cpp -std=c++11
patten@patten-hp:~/workspace/others/cpp/demo$ ./a.out 
I like to code in C
I like to code in C++
I like to code
patten@patten-hp:~/workspace/others/cpp/demo$

replace()

函数原型

string& replace (size_t pos, size_t len, const string& str);  //用str替换指定字符串从起始位置pos开始长度为len的字符 

string& replace (const_iterator i1, const_iterator i2, const string& str);  //用str替换迭代器起始位置i1和结束位置i2的字符 

string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);  //用str的指定子串(给定起始位置subpos和长度sublen)替换从指定位置上的字符串 (给定起始位置pos和长度len)

string& replace(size_t pos, size_t len, const char* s);  //string转char*时编译器可能会报出警告,不建议这样做; 用s替换从指定位置pos开始长度为len的字符串

string& replace (const_iterator i1, const_iterator i2, const char* s);  //string转char*时编译器可能会报出警告,不建议这样做; 用str替换从指定迭代器起始位置i1和结束位置i2的字符

string& replace(size_t pos, size_t len, const char* s, size_t n);  //string转char*时编译器可能会报出警告,不建议这样做; 用s的前n个字符替换从开始位置pos长度为len的字符串

string& replace (const_iterator i1, const_iterator i2, const char* s, size_t n); //string转char*时编译器可能会报出警告,不建议这样做; 用s的前n个字符替换指定迭代器位置(从i1到i2)的字符串

string& replace (size_t pos, size_t len, size_t n, char c);  //用重复n次的c字符替换从指定位置pos长度为len的内容

string& replace (const_iterator i1, const_iterator i2, size_t n, char c);  //用重复n次的c字符替换从指定迭代器位置(从i1开始到结束)的内容 

函数功能

replace()函数包含于头文件#include<string>中。
泛型算法replace()把队列中与给定值相等的所有值替换为另一个值,整个队列都被扫描,即此算法的各个版本都在线性时间内执行———其复杂度为O(n)。
replace()的执行要遍历由区间[frist,last]限定的整个队列,以把old_value替换成new_value
如果replace()找不到要查找的字符串,它返回string::npos。数据成员nposstring类的一个静态常量成员,它表示一个不存在的字符位置。

使用示例

#include <iostream>
#include <string>

using namespace std;

int main() {
  string str = "he is@ a@ good boy";
  str = str.replace(str.find("a"), 2, "#");  //从第一个a位置开始的两个字符替换成#
  cout << str << endl << endl;

  str = "he is@ a@ good boy";
  str = str.replace(str.begin(), str.begin() + 5, "#");  //用#替换从begin位置开始的5个字符
  cout << str << endl << endl;

  str = "he is@ a@ good boy";
  string substr = "12345";
  str = str.replace(0, 5, substr, substr.find("1"), 4);  //用substr的指定字符串替换str指定字符串
  cout << str << endl << endl;

  str = "he is@ a@ good boy";
  char* str1 = "12345";
  str = str.replace(0, 5, str1);  //用str替换从指定位置开始长度为5的字符串
  cout << str << endl << endl;

  str = "he is@ a@ good boy";
  str = str.replace(str.begin(), str.begin() + 6, str1);  //用str替换从指定迭代器位置的字符串
  cout << str << endl << endl;

  str = "he is@ a@ good boy";
  str = str.replace(0, 6, str1, 4);  //用str1的前4个字符串替换从位置0~6的字符串
  cout << str << endl << endl;

  str = "he is@ a@ good boy";
  str = str.replace(str.begin(), str.begin() + 6, str1,
                    4);  //用str1的前4个字符串替换从位置0~6的字符串
  cout << str << endl << endl;

  str = "he is@ a@ good boy";
  char  c = '#';
  str = str.replace(0,6,3,c);   //用重复3次的str1字符替换的替换从位置0~6的字符串
  cout << str << endl << endl;

  str = "he is@ a@ good boy";
  str = str.replace(str.begin(),str.begin()+6,3,c);   //用重复3次的str1字符替换的替换从指定迭代器位置的内容 
  cout << str << endl << endl;


  return 0;
}

编译输出

patten@patten-hp:~/workspace/others/cpp/demo$ g++ main.cpp -std=c++11
main.cpp: In function ‘int main()’:
main.cpp:21:16: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
   char* str1 = "12345";
                ^
patten@patten-hp:~/workspace/others/cpp/demo$ ./a.out 
he is@ # good boy

#@ a@ good boy

1234@ a@ good boy

12345@ a@ good boy

12345 a@ good boy

1234 a@ good boy

1234 a@ good boy

### a@ good boy

### a@ good boy

patten@patten-hp:~/workspace/others/cpp/demo$

追加、插入和连接字符串

使用示例

#include <cassert>
#include <iostream>
#include <string>

using namespace std;

int main() {
  string bigNews("I saw Elvis in a UFO. ");
  printf("bigNews = %s \n", bigNews.c_str());
  printf("bigNews.length() = %ld \n", bigNews.length());
  printf("bigNews.size() = %ld \n", bigNews.size());//由于"UFO."后面还有一个"",加上空格所以是22
  printf("bigNews.capacity() = %ld \n", bigNews.capacity());

  cout<<endl;

  bigNews.insert(1, " thought I");
  printf("bigNews = %s \n", bigNews.c_str());
  printf("bigNews.length() = %ld \n", bigNews.length());
  printf("bigNews.size() = %ld \n", bigNews.size());
  printf("bigNews.capacity() = %ld \n", bigNews.capacity());

  cout<<endl;

  bigNews.insert(32, " I'm afraid of the condition.");
  printf("bigNews = %s \n", bigNews.c_str());
  printf("bigNews.length() = %ld \n", bigNews.length());
  printf("bigNews.size() = %ld \n", bigNews.size());
  printf("bigNews.capacity() = %ld \n", bigNews.capacity());

  cout<<endl;

  bigNews.reserve(500);
  bigNews.append("I've been working too hard.");
  printf("bigNews = %s \n", bigNews.c_str());
  printf("bigNews.length() = %ld \n", bigNews.length());
  printf("bigNews.size() = %ld \n", bigNews.size());
  printf("bigNews.capacity() = %ld \n", bigNews.capacity());

  cout<<endl;

  bigNews.resize(50);
  printf("bigNews = %s \n", bigNews.c_str());
  printf("bigNews.length() = %ld \n", bigNews.length());
  printf("bigNews.size() = %ld \n", bigNews.size());
  printf("bigNews.capacity() = %ld \n", bigNews.capacity());

  return 0;
}

编译输出

patten@patten-hp:~/workspace/others/cpp/demo$ g++ main.cpp -std=c++11
patten@patten-hp:~/workspace/others/cpp/demo$ ./a.out 
bigNews = I saw Elvis in a UFO.  
bigNews.length() = 22 
bigNews.size() = 22 
bigNews.capacity() = 22 

bigNews = I thought I saw Elvis in a UFO.  
bigNews.length() = 32 
bigNews.size() = 32 
bigNews.capacity() = 44 

bigNews = I thought I saw Elvis in a UFO.  I'm afraid of the condition. 
bigNews.length() = 61 
bigNews.size() = 61 
bigNews.capacity() = 88 

bigNews = I thought I saw Elvis in a UFO.  I'm afraid of the condition.I've been working too hard. 
bigNews.length() = 88 
bigNews.size() = 88 
bigNews.capacity() = 500 

bigNews = I thought I saw Elvis in a UFO.  I'm afraid of the 
bigNews.length() = 50 
bigNews.size() = 50 
bigNews.capacity() = 500 
patten@patten-hp:~/workspace/others/cpp/demo$

这个例子证实了,即使可以安全地避免分配及管理string对象所占用的存储空间的工作,C++ string类也提供了几个工具以便监视和管理它们的存储规模。

使用非成员重载运算符连接

对于一个学习C++string处理的C程序员来说,等待他的最令人信息的发现之一就是,借助Operator+Operator+=可以如此轻而易举地实现string的合并与追加。这些运算符使合并字符串的操作在语法上类似于数值型数据的加法运算:

使用示例

#include <iostream>
#include <string>
#include <cassert>

using namespace std;

int main(){
  string s1("This ");
  string s2("That ");
  string s3("The other ");

  s1 = s1 + s2;
  cout<< s1 << endl;
  assert("This That " == s1);
  s1 += s3;
  cout<< s1 << endl;
  assert("This That The other " == s1);
  s1 += s3 + s3[4] + "ooh lala";
  cout<< s1 << endl;
  assert("This That The other The other oooh lala" == s1);
  s1 = "head string " + s1;
  cout<< s1 << endl;
  assert("head string This That The other The other oooh lala" == s1);

  return 0;
}

编译输出

patten@patten-hp:~/workspace/others/cpp/demo$ g++ main.cpp -std=c++11
patten@patten-hp:~/workspace/others/cpp/demo$ ./a.out 
This That 
This That The other 
This That The other The other oooh lala
head string This That The other The other oooh lala
patten@patten-hp:~/workspace/others/cpp/demo$

致谢

Lavi_qq_2910138025C中string append函数的使用与字符串拼接
bat67整理:C中sprintf()函数的使用详解
正在加载……C++ string类insert用法总结
我要出家当道士C中string类型insert方法用法集锦
柳婼 の blogC:string类中size()和length()的区别
lakeoneC++ string的size()和length()函数没有区别
lonywc++ string类length()(size())函数返回值–无符号数
QilongPanC中string的Reserve() 和 capacity()
i永无止境c string中的reserve()和resize()
c++ string resize
Areationc中resize()函数
cai_niaocainiaoC replace() 函数用法