c++ string 无法通过下标访问_C++[04] string成员函数之赋值函数assign以及重载运算符=...

首先补充一下,昨天的append和重载运算符+=,

正常调用append

#include #include using namespace std;// appendint main(int argc, char* argv[]){  string str1 = "Hello";  string str2 = "_World";  cout << "str1=" << str1 << ",\tstr2=" << str2 << endl << endl;  // 01. string& append(const_iterator first, const_iterator last);  not include the last char  // 这里的两个参数,是两个迭代器Iterator string类型本身也是支持迭代器的  cout << "01. string& append(const_iterator first, const_iterator last);" << endl  << "not include the last char" << endl<< endl;  str1.append(str2.begin()+1, str2.end());  // 将World追加到Hello之后 结果HelloWorld  cout << "str1.append(str2.begin()+1, str2.end())->" << str1 << endl;  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  str1.append(str2.begin()+2, str2.end()-2);  // 将or追加到Hello之后 结果Helloor  cout << "str1.append(str2.begin()+2, str2.end()-2)->" << str1 << endl;  cout << "####################" << endl << endl;      // 02. string& append(unsigned int num, char ch);   // 在字符串末尾添加num个字符ch  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  cout << "02. string& append(unsigned int num, char ch);" << endl<< endl;  str1.append(10, str2[1]); // 将 str2[1] -> W 重复10次追加到str1结尾 结果 HelloWWWWWWWWWW   cout << "str1.append(10, str2[1])->" << str1 << endl;  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  str1.append(5, str2[5]);  // 将 str2[5] -> d 重复10次追加到str1结尾 结果 Helloddddd  cout << "str1.append(5, str2[5])->" << str1 << endl;  cout << "####################" << endl << endl;  // 03. string& append(const char *str);    // 字符串结尾添加 字符串常量  // 看源码可以知道,这里调用了 append(const char* str, unsigned int length)  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值    cout << "03. string& append(const char *str)" << endl<< endl;      // 这里使用了前面讲到的c_str()  str1.append(str2.c_str()); // 将str2.c_str()  也就是返回的字符串常量追加到str1 结果Hello_World  cout << "str1.append(str2.c_str())->" << str1 << endl;  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  str1.append("_MyGod");   // 将_MyGod  也就是返回的字符串常量追加到str1 结果Hello_MyGod  cout << "str1.append(\"_MyGod\")->" << str1 << endl;  cout << "####################" << endl << endl;    // 04.  string& append(const char *str, int length);  // 字符串结尾添加 字符串常量的一部分或者全部  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  cout << "04. string& append(const char *str, unsigned int length)" << endl<< endl;    // 这里用到了前面介绍的 length()  str1.append(str2.c_str(), str2.length()-3);  cout << "str1.append(str2.c_str(), str2.length()-3)->" << str1 << endl;    str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  str1.append(str2.c_str(), str2.length());  // 超出str2长度的情况  cout << "str1.append(str2.c_str(), str2.length())->" << str1 << endl;  cout << "####################" << endl << endl;        //  05. string & append(const string& obj, int id, int length)  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  cout << "05. string& append(const string& obj, unsigned int id, unsigned int length)" << endl<< endl;    str1.append(str2, str2.length()-5, 3);    cout << "str1.append(str2, str2.length()-5, 3)->" << str1 << endl;    str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  str1.append(str2, str2.length()-5, 5);  cout << "str1.append(str2, str2.length()-5, 5)->" << str1 << endl;  cout << "####################" << endl << endl;    // 06. string& append(const string &obj);  // 调用string对象对str1字符追加  // 查看源码可以知道 调用了append(const string& obj, 0, pos)  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  cout << "06. string& append(const string &obj)" << endl<< endl;    str1.append(str2);  cout << "str1.append(str2)->" << str1 << endl;  cout << "####################" << endl << endl;    system("pause");    return 0;}

结果显示

9dfe4d15e74dbfe9d3e683cb32059829.png

重载运算符

#include #include using namespace std;// operator+=int main(int argc, char* argv[]){  string str1 = "Hello";  string str2 = "_World";  cout << "str1=" << str1 << ",\tstr2=" << str2 << endl << endl;  str1 += str2;  cout << "string& operator(const string& obj){return append(obj);}" << endl;  cout << "str1.operator+=(str2)->" << str1 << endl;  cout << "####################" << endl << endl;  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  str1 += str2.c_str();  cout << "string& operator(const char* str){return append(str);}" << endl;  cout << "str1.operator+=(str2.c_str())->" << str1 << endl;  cout << "####################" << endl << endl;  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  str1 += '#';  cout << "string& operator(char ch){return append(1, ch);}" << endl;  cout << "str1.operator+=('#')->" << str1 << endl;  cout << "####################" << endl << endl;  system("pause");  return 0;}

结果显示

d669aec0e1d911e4e5d027a45842da15.png

非正常的调用append

#include #include using namespace std;int main(int argc, char* argv[]){  string str1 = "Hello";  string str2 = "_World";  cout << "str1=" << str1 << ",\tstr2=" << str2 << endl << endl;    // 04.  string& append(const char *str, int length);  // 字符串结尾添加 字符串常量的一部分或者全部  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  cout << "04. string& append(const char *str, unsigned int length)" << endl<< endl;    // 这里用到了前面介绍的 length()  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  cout <"超出字符串常量长度" <endl;   str1.append(str2.c_str(), str2.length()+3);  // 超出str2长度的情况  cout <"str1.append(5, str2[5])->" <endl;  cout << "####################" << endl << endl;    //  05. string & append(const string& obj, int id, int length)  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  cout << "05. string& append(const string& obj, unsigned int id, unsigned int length)" << endl<< endl;  cout << "超出字符串常量长度" << endl;  str1.append(str2, str2.length()-5, 8);   cout << "str1.append(str2, str2.length()-5, 8)->" << str1 << endl;  str1 = "hello", str2 = "_World";   // 恢复 str1 str2的值  cout <"下标从负值开始" <endl;  str1.append(str2, str2.length()-10, 8);   cout << "str1.append(str2, str2.length()-10, 11)->" << str1 << endl;  cout << "####################" << endl << endl;      system("pause");  return 0;}

结果显示

1002cbe624047c97ab728a799a6b58b9.png

从结果可以看出,当追加字符串常量,设定追加长度大于字符串长度的时候,是可以正常追加的。而如果下标索引小于0 ,则是不被允许的。

#######完美的分割线c618176a8f76196fa95efe40cb7e7ffd.pngc618176a8f76196fa95efe40cb7e7ffd.pngc618176a8f76196fa95efe40cb7e7ffd.pngc618176a8f76196fa95efe40cb7e7ffd.pngc618176a8f76196fa95efe40cb7e7ffd.pngc618176a8f76196fa95efe40cb7e7ffd.png#######

好了,开始介绍今天的赋值函数assign

同样,先看定义,

string& operator=(const string& obj)      {return (assign(obj)); }string& operator=(const char *str)       {return (assign(str)); }string& operator=(char ch)          {return (assign(1, ch)); }string& assign(const string& obj)    {return (assign(obj, 0, npos)); }string& assign(const char *str)    {return (assign(str, _Tr::length(str))); }string& assign(_It _F, _It _L)  {return (replace(begin(), end(), _F, _L)); }string& assign(const string& obj, unsigned int _P, unsigned int_M){if (obj.size() size_type _N = obj.size() - _P;if (_M if (this == &obj)  erase((size_type)(_P + _N)), erase(0, _P);else if (0 < _N && _N == obj.size()  && _Refcnt(obj.c_str()) 1  && allocator == obj.allocator)  {_Tidy(true);  _Ptr = (char *)obj.c_str();  _Len = obj.size();  _Res = obj.capacity();  ++_Refcnt(_Ptr); }else if (_Grow(_N, true))  {_Tr::copy(_Ptr, &obj.c_str()[_P], _N);  _Eos(_N); }return (*this); }string& assign(const char *str, size_type _N)  {if (_Grow(_N, true))    {_Tr::copy(_Ptr, str, _N);    _Eos(_N); }  return (*this);   }    string& assign(size_type _N, char ch){if (_N == npos)  _Xlen();if (_Grow(_N, true))  {_Tr::assign(_Ptr, _N, ch);  _Eos(_N); }return (*this); }

可以看到,重载运算符= 调用了assign。测试代码,查看assign的功能以及结果

  cout << "string& operator=(const char *str)" << endl;  string str1 = "Hello";  string str2 = "World";  cout << "str1 = \"Hello\"->" << std1 << endl;  cout << "str2 = \"World\"->" << std2 << endl;  cout << "####################" << endl << endl;    cout << "string& operator=(const string& obj)" << endl;  string str3 = str1;  cout << "str3 = str1->" << std3 << endl;    cout << "####################" << endl << endl;    cout << "string& operator=(char ch)" << endl;  string str3 = 'W';  cout << "str3 = \'W\'->" << std3 << endl;  cout << "####################" << endl << endl;

df05d16edc48353960036af50cf0b0a1.png

assign函数

string str1;  string str2;    // string& assign(const char *str)    {return (assign(str, _Tr::length(str))); }  cout << "01. string& assign(const char *str)" << endl;  str1.assign("Hello");  cout << "str1.assign(\"Hello\")->" << str1 << endl;  cout << "####################" << endl << endl;    // string& assign(const char *str, unsigned int length);  cout << "02. string& assign(const char *str, unsigned int length)" << endl;  str2.assign("World", 3);  cout << "str2.assign(\"World\", 3)->" << str2 << endl;  str2.assign("World", 5);  cout << "str2.assign(\"World\", 5)->" << str2 << endl;  cout << "####################" << endl << endl;      //   string& assign(const string& obj)    {return (assign(obj, 0, npos)); }  cout << "03. string& assign(const string& obj)" << endl;  str2.assign(str1);  cout << "str2.assign(str1)->" << str2 << endl;  cout << "####################" << endl;        //   string& assign(const string& obj, unsigned int id, unsigned int length)  cout << "04. string& assign(const char *str, unsigned int id, unsigned int length)" << endl;  str2.assign(str1, 1, 3);  cout << "str2.assign(str1, 1, 3)->" << str2 << endl;    str2.assign(str1, 1, 2);  cout << "str2.assign(str1, 1, 2)->" << str2 << endl;  cout << "####################" << endl;        //   string& assign(unsigned int num, char ch);  cout << "05. string& assign(unsigned int num, char ch)" << endl;  str2.assign(5, '#');  cout << "str2.assign(5, \'#\')->" << str2 << endl;  cout << "####################" << endl;        //   string& assign(const_iterator first, const_iterator last)  cout << "06. string& assign(const_iterator first, const_iterator last)" << endl;  str2.assign(str1.begin(), str1.end()-1);  cout << "str2.assign(\"World\", 5)->" << str2 << endl;  cout << "####################" << endl;

显示结果

e37ca6691e15ea65487352f3ceb1d495.png

 对于图中红色标记的两个函数,

对于函数2,当设定长度大于字符串常量的长度的情况;

对于函数4,当设定长度大于字符串长度的情况,以及下标小于0的情况。

下面单独测试

  string str1="Hello";  string str2;  // string& assign(const char *str, unsigned int length);  cout << "02. string& assign(const char *str, unsigned int length)" << endl;  cout << "长度超出字符串常量长度" << endl;  str2.assign("World", 8);  cout << "str2.assign(\"World\", 8)->" << str2 << endl;  cout << "####################" << endl << endl;  //   string& assign(const string& obj, unsigned int id, unsigned int length)  cout << "04. string& assign(const char *str, unsigned int id, unsigned int length)" << endl;  cout << "长度超出字符串常量长度" << endl;  str2.assign(str1, 3, 5);  cout << "str2.assign(str1, 3, 5)->" << str2 << endl;  cout << "起始下标负值" << endl;  str2.assign(str1, 3, 5);  cout << "str2.assign(str1, 3, 5)->" << str2 << endl;

显示结果

d70fe19b8b57e37e61a027708792dd98.png

可以看到,当设定长度大于字符串常量的长度,以及大于参数字符串大小的时候,都能够处理。

而当引用参数字符串下标小于0时,则是不被允许的。

好了,今天就介绍到这里。剧透一下,下一次介绍 find系列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值