C++ string类型小结


参考 权威网站
左边的目录列举了关于string的 一些 成员。

构造函数

默认 string();
从已有复制 string (const string& str);
从已有剪辑 string (const string& str, size_t pos, size_t len = npos);
从字符数组录入 string (const char* s);
从字符数组录入n位
string (const char* s, size_t n);
用字符填充
string (size_t n, char c);
从迭代器填充
template <class InputIterator>
  string  (InputIterator first, InputIterator last);

析构函数:就普通析构函数没什么好讲的你又用不到

string.append()

在已有字符串后面添加字符串

正常的添加 string& append (const string& str);
截取后添加 string& append (const string& str, size_t subpos, size_t sublen);
用字符数组添加 string& append (const char* s);
截取字符数组添加 string& append (const char* s, size_t n);
string& append (const char* s, size_t subpos, size_t sublen)
添加单一字符 string& append (size_t n, char c);
用迭代器添加
template <class InputIterator>
   string& append (InputIterator first, InputIterator last);

而且这个函数不仅调用可以改变字符串,也可以直接返回改变后的字符串

cout << a.append("lover!");

这样既改变了a同时也可以直接输出改变后的a

string.assign()

重新构造字符串,跟构造函数是一样的但是你用不了构造函数只能来用这个

默认 string& assign (const string& str);
截取 string& assign (const string& str, size_t subpos, size_t sublen);
字符数组 string& assign (const char* s);
截取字符数组 string& assign (const char* s, size_t n);
string& assign(const char* s, size_t subpos, size_t sublen);
单一字符填充
string& assign (size_t n, char c);
迭代器填充	
template <class InputIterator>
   string& assign (InputIterator first, InputIterator last);

string.at()

返回字符串某个位置的字符

char& at (size_t pos);
const char& at (size_t pos) const;

(好像上下两个没什么区别嘛……)
注意这里是从0开始的。
如果你给的数字大于该字符串的长度,就会抛出out_of_range类型异常

string.back()

c++11 only
返回的是字符串最后一个字符的引用

char& back();
const char& back() const;

但是正常编译的版本好像没有这个功能……需要加上-std=c++11编译选项。

string.begin()

string.end()
返回第一个字符的迭代器

iterator begin();
const_iterator begin() const;

权威网站举了个例子

int main ()
{
  std::string str ("Test string");
  for ( std::string::iterator it=str.begin(); it!=str.end(); ++it)
    std::cout << *it;
  std::cout << '\n';

  return 0;
}

迭代器是可以自增的,曾经也有某位大佬写过迭代器,在篇文章中用浏览器的搜索功能搜索“迭代器”就可以找到

string.capasity()

返回的是string所占的内存空间。用字节表示

size_t capacity() const;

他没什么用因为他的返回值只是不小于字符串长度

// comparing size, length, capacity and max_size
int main ()
{
  std::string str ("Test string");
  std::cout << "size: " << str.size() << "\n";
  std::cout << "length: " << str.length() << "\n";
  std::cout << "capacity: " << str.capacity() << "\n";
  std::cout << "max_size: " << str.max_size() << "\n";
  return 0;
}

可能会输出

size: 11
length: 11
capacity: 15
max_size: 429496729

string.cbegin()

c++11 only

// string::cbegin/cend
int main ()
{
  std::string str ("Lorem ipsum");
  for (auto it=str.cbegin(); it!=str.cend(); ++it)
    std::cout << *it;
  std::cout << '\n';

  return 0;
}

(真是的用string.begin()和string.end()不好吗)

string.clear()

清空字符串

int main ()
{
  char c;
  std::string str;
  std::cout << "Please type some lines of text. Enter a dot (.) to finish:\n";
  do {
    c = std::cin.get();
    str += c;
    if (c=='\n')
    {
       std::cout << str;
       str.clear();
    }
  } while (c!='.');
  return 0;
}

string.compare()

比较当前字符串和给定字符串

默认的全文比较 int compare (const string& str) const;
默认的截取比较 int compare (size_t pos, size_t len, const string& str) const;
这里的截取是a.compare(size_t pos, size_t len, const string& str) 截取a从pos后的第len位和整个str比较
都可以的截取比较 int compare (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) const;
截取a从pos后的len位和str从subpos后的sublen为进行比较
然后就是把所有的string类型改成char* 类型
int compare (const char* s) const;
int compare (size_t pos, size_t len, const char* s) const;
然后由于你传入char* 所以是没有subpos的,只有sublen,也就是截取前n位和你比较
int compare (size_t pos, size_t len, const char* s, size_t n) const;

返回值:
str.compare(cmp_str);

0:两个字符串相等
<0:str比cmp_str小
>0:str比cmp_str大

这里的字符串的大小定义是:
小:从前往后第一个不相同的字符,str比cmp_str的字典序小,也就是找到最小的i,使得str[i]!=cmp_str[i],然后再比较字典序。或者str是cmp_str的前缀
大:除了小和等的情况外的所有情况(废话)
复杂度:线性
异常:如果指定长度大于字符串长度,会抛出out_of_range类型异常

string.copy()

复制字符串

size_t copy (char* s, size_t len, size_t pos = 0) const;

a.copy(s, len, pos)表示把a从pos后len位复制到s。注意s才是被覆盖的那个。
返回成功复制的长度。
会抛出out_of_range类型异常

string.crbegin()

string.crend()
c++11 only

const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;

返回的是关于string的迭代器const_reverse_iterator,就是反向迭代器。返回的crbegin()其实就是字符串结尾,crend()就是字符串开头
这个迭代器的运算规则也是反向的,也就是it=crbegin(); it++其实是反向增加,也就是逆序遍历
权威网站给了一个逆向输出的代码

int main ()
{
  std::string str ("lorem ipsum");
  for (auto rit=str.crbegin(); rit!=str.crend(); ++rit)
    std::cout << *rit;
  std::cout << '\n';

  return 0;
}

(真是的用begin和end会死啊)

string.c_str()

把string类型的变量转变为char*类型

const char* c_str() const;

有很多c++的函数要求传入的参数都是const char, 也就是字符数组。
string虽然被称为字符串类型,但是和const char
却不是同一个类型。所以string里面就有这样一个成员函数,把string类型存储的字符串转换为字符数组类型。

string.data()

const char* data() const;

(这东西和c_str()有区别吗)

string.empty()

告诉你这个字符串是不是为空(也就是长度是否为0)

bool empty() const;

string.erase()

删除本字符串的一部分,剪短他的长度

sequence (1)	
 string& erase (size_t pos = 0, size_t len = npos);
character (2)	
iterator erase (iterator p);
range (3)	
     iterator erase (iterator first, iterator last);
  1. sequence
    这里传入了默认参数,如果什么都没有就会删掉整个字符串。
    如果只有一个参数就是默认先填充第一个参数,也就是起始位置,从你给的位置一路删除到末尾。
    如果有俩参数,就是正常的从pos一路删除len位
    返回删除后的字符串的引用。
  2. character
    传入一个迭代器,删除这个迭代器指向的字符
    返回删除后迭代器指向的字符。
    如果我们用字符数组来表示字符串的话,删除了char[5],那么删除之后因为字符串还要连续那么char[6]就会补上来,所以返回的字符就是原来的char[6]
  3. range
    用俩迭代器来表示一个范围,删除这个范围内的所有字符。
    然后返回这个范围的下一个字符。
    如果删除[begin,end)的话,那么返回的便是原来的char[end]

(自己去写代码验证一下啊?)

string.find()

string (1)	
size_t find (const string& str, size_t pos = 0) const;
c-string (2)	
size_t find (const char* s, size_t pos = 0) const;
buffer (3)	
size_t find (const char* s, size_t pos, size_t n) const;
character (4)	
size_t find (char c, size_t pos = 0) const;
  1. string
    寻找str,从第pos位开始。
    a.find(b,pos);这个pos是指a的pos,把a从pos开始找。
    找到的是原字符串中的位置
  2. c_str
    很正常的字符数组。
  3. buffer
    截取s的前n位和a比较,pos和第一个函数的用法一样。
  4. character
    找到一个字符。

时间复杂度:未定义,但应该在两个要匹配的长度相乘上线性。

string.find_first_not_of(str)

从当前字符里找到第一个不在str里面的字符。

string (1)	
size_t find_first_not_of (const string& str, size_t pos = 0) const;
c-string (2)	
size_t find_first_not_of (const char* s, size_t pos = 0) const;
buffer (3)	
size_t find_first_not_of (const char* s, size_t pos, size_t n) const;
character (4)	
size_t find_first_not_of (char c, size_t pos = 0) const;

在当前string里面找到第一个不在给定字符串str里面的字符并返回它的位置
pos表示忽略当前字符串的前pos-1位(从第pos位开始考虑,pos也包括进去了)
n就是取字符数组的前n位。

时间复杂度:未定义,应该是两个要匹配的字符串长度相乘

string.find_first_of(str)

...直译:在当前字符串中找到第一个在给定字符串str中的字符

string (1)	
size_t find_first_of (const string& str, size_t pos = 0) const;
c-string (2)	
size_t find_first_of (const char* s, size_t pos = 0) const;
buffer (3)	
size_t find_first_of (const char* s, size_t pos, size_t n) const;
character (4)	
size_t find_first_of (char c, size_t pos = 0) const;

用法和上面那个一样。

string.find_last_not_of(str)

string.find_last_of(str)

...直译...

string.front()

c++11 only
返回字符串第一个字符的引用

      char& front();
const char& front() const;

string.get_allocator()

我不懂
比赛应该不会考吧……
参考资料1
参考资料2

string.insert()

插入

string (1)	
// 在pos位置插入str
 string& insert (size_t pos, const string& str);
substring (2)	
// 截取str的[subpos,subpos+sublen)插入到str的pos位置
 string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
c-string (3)	
// 在pos位置插入s
 string& insert (size_t pos, const char* s);
buffer (4)	
// 在pos位置插入s的前n位
 string& insert (size_t pos, const char* s, size_t n);
fill (5)	
// 在pos位置插入n个c
 string& insert (size_t pos, size_t n, char c);
// 在p的迭代器后面插入n个c
    void insert (iterator p, size_t n, char c);
single character (6)	
// 在p迭代器后面插入字符c
iterator insert (iterator p, char c);
range (7)	
// 在p迭代器后面插入[first, last)迭代器之间的字符
template <class InputIterator>
   void insert (iterator p, InputIterator first, InputIterator last);

参考权威网站提供的代码

// 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;
}

时间复杂度:未定义,但应该和新字符串的长度成线性。

string.length()

返回当前字符串的长度

size_t length() const;

string.max_size()

返回当前系统下字符串可以到达的最大长度。

size_t max_size() const;

string.operator+=

首先肯定要知道也有+这个重载运算符的
就是用来连接俩字符串

string (1)	
string& operator+= (const string& str);
c-string (2)	
string& operator+= (const char* s);
character (3)	
string& operator+= (char c);

这个……看函数原型就知道了把……
给出经过个人修改的权威网站的样例代码:

// string::operator+=
#include <iostream>
#include <string>

int main ()
{
  std::string name ("John");
  std::string family ("Smith");
  name + " K. ";         // c-string
  name += family;         // string
  name += '\n';           // character

  std::cout << name;
  return 0;
}

时间复杂度:未定义,但应该和新字符串的长度成线性。

string.operator=

很简单的一个赋值语句

string (1)	
string& operator= (const string& str);
c-string (2)	
string& operator= (const char* s);
character (3)	
string& operator= (char c);

string.operator[]

从此之后你可以像访问字符数组那样用下标来访问字符串。

      char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

string.pop_back()

c++11 only
删除字符串的最后一个字符

void pop_back()

string.push_back()

增加一个字符

void push_back(char c);

比如这样:

// string::push_back
#include <iostream>
#include <fstream>
#include <string>

int main ()
{
  std::string str("b");
  str.push_back('a');
  std::cout << str << '\n';
  return 0;
}

string.rbegin()

string.rend()
反过来遍历……这个和crbegin是一样的

// string::rbegin/rend
#include <iostream>
#include <string>

int main ()
{
  std::string str ("now step live...");
  for (std::string::reverse_iterator rit=str.rbegin(); rit!=str.rend(); ++rit)
    std::cout << *rit;
  return 0;
}

string.replace()

用给定字符串来代替原字符串里面的一些内容

// 用str来代替[pos,pos+len)之间的字符
// str的长度不受len的限制
string& replace (size_t pos,  size_t len,  const string& str);
// 用str来代替两个迭代器之间的字符
string& replace (iterator i1, iterator i2, const string& str);
substring (2)	
// 用str[subpos,subpos+sublen)来代替[pos,pos+len)之间的字符。
string& replace (size_t pos,  size_t len,  const string& str,
                 size_t subpos, size_t sublen);
c-string (3)	
// 用字符数组来代替
string& replace (size_t pos,  size_t len,  const char* s);
string& replace (iterator i1, iterator i2, const char* s);
buffer (4)	
// 用字符数组的前n个来代替
string& replace (size_t pos,  size_t len,  const char* s, size_t n);
string& replace (iterator i1, iterator i2, const char* s, size_t n);
fill (5)	
// 用n个字符c来代替
string& replace (size_t pos,  size_t len,  size_t n, char c);
string& replace (iterator i1, iterator i2, size_t n, char c);
range (6)	
// 给定字符串str用迭代器来表示。
template <class InputIterator>
  string& replace (iterator i1, iterator i2,
                   InputIterator first, InputIterator last);

贴上来自权威网站的代码

// replacing in a string
#include <iostream>
#include <string>

int main ()
{
  std::string base="this is a test string.";
  std::string str2="n example";
  std::string str3="sample phrase";
  std::string str4="useful.";

  // replace signatures used in the same order as described above:

  // Using positions:                 0123456789*123456789*12345 // 这个是对齐给你看字符位置的
  std::string str=base;           // "this is a test string."
  str.replace(9,5,str2);          // "this is an example string." (1)
  str.replace(19,6,str3,7,6);     // "this is an example phrase." (2)
  str.replace(8,10,"just a");     // "this is just a phrase."     (3)
  str.replace(8,6,"a shorty",7);  // "this is a short phrase."    (4)
  str.replace(22,1,3,'!');        // "this is a short phrase!!!"  (5)

  // Using iterators:                                               0123456789*123456789* // 这个也是对齐给你看字符位置的。
  str.replace(str.begin(),str.end()-3,str3);                    // "sample phrase!!!"      (1)
  str.replace(str.begin(),str.begin()+6,"replace");             // "replace phrase!!!"     (3)
  str.replace(str.begin()+8,str.begin()+14,"is coolness",7);    // "replace is cool!!!"    (4)
  str.replace(str.begin()+12,str.end()-4,4,'o');                // "replace is cooool!!!"  (5)
  str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is useful."    (6)
  std::cout << str << '\n';
  return 0;
}

时间复杂度:未定义,应该在新字符串中成线性。

string.reserve()

不要跟我一样傻乎乎写成了reverse
用来扩容(?)的,给将来的字符串保留更多空间。

void reserve (size_t n = 0);
// string::reserve
#include <iostream>
#include <fstream>
#include <string>

int main ()
{
  std::string str("0123");

  using std::cout;
  using std::endl;
  cout<<str.capacity()<<endl;
  str.reserve(100);
  cout<<str.capacity()<<endl;
  return 0;
}

string.resize()

重新调整大小

void resize (size_t n);
void resize (size_t n, char c);

如果n小于当前大小就直接砍掉
如果n大于当前大小就用默认(int)0或者给定字符c填充

string.rfind()

和find的功能一样,只不过从后向前找到第一个

string (1)	
// 这里截断还是从截断[0,pos)之间的字符进行判断
size_t rfind (const string& str, size_t pos = npos) const;
c-string (2)	
size_t rfind (const char* s, size_t pos = npos) const;
buffer (3)	
size_t rfind (const char* s, size_t pos, size_t n) const;
character (4)	
size_t rfind (char c, size_t pos = npos) const;

string.shrink_to_fit()

要求字符串通过判断当前储存的长度来智能缩小申请的容量

void shrink_to_fit();

可能说的不是很清楚,运行一下权威网站的代码就知道了。

// string::shrink_to_fit
#include <iostream>
#include <string>

int main ()
{
  std::string str (100,'x');
  std::cout << "1. capacity of str: " << str.capacity() << '\n';

  str.resize(10);
  std::cout << "2. capacity of str: " << str.capacity() << '\n';

  str.shrink_to_fit();
  std::cout << "3. capacity of str: " << str.capacity() << '\n';

  return 0;
}

string.size()

你确定这和length不是一个东西?

size_t size() const;

string.substr()

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

截取并返回当前字符串的[pos,pos+len)
不会修改原字符串。

时间复杂度:未定义,一般和返回的字符串成线性。

string.swap()

和给定字符串交换值,两个字符串的值都会被修改。

void swap (string& str);

时间复杂度:常数

[string.npos]

就是最大长度
unsigned long long 下的-1

static const size_t npos = -1;

getline(string)

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

从输入流is读取一行(以'\n'位分界)字符串保存到str

relational operators(string)

就是一些自定义的重载运算符……大部分都是用来比较的,大小关系在compare函数里面有说明

(1)	
bool operator== (const string& lhs, const string& rhs);
bool operator== (const char*   lhs, const string& rhs);
bool operator== (const string& lhs, const char*   rhs);
(2)	
bool operator!= (const string& lhs, const string& rhs);
bool operator!= (const char*   lhs, const string& rhs);
bool operator!= (const string& lhs, const char*   rhs);
(3)	
bool operator<  (const string& lhs, const string& rhs);
bool operator<  (const char*   lhs, const string& rhs);
bool operator<  (const string& lhs, const char*   rhs);
(4)	
bool operator<= (const string& lhs, const string& rhs);
bool operator<= (const char*   lhs, const string& rhs);
bool operator<= (const string& lhs, const char*   rhs);
(5)	
bool operator>  (const string& lhs, const string& rhs);
bool operator>  (const char*   lhs, const string& rhs);
bool operator>  (const string& lhs, const char*   rhs);
(6)	
bool operator>= (const string& lhs, const string& rhs);
bool operator>= (const char*   lhs, const string& rhs);
bool operator>= (const string& lhs, const char*   rhs);
posted @ 2021-09-15 15:33  IdanSuce  阅读(336)  评论(0编辑  收藏  举报