1 #include <string>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 
  8 int to_lower(int c)
  9 {
 10     if (isupper(c))
 11     {
 12         return (c+32);
 13     }
 14 
 15     return c;
 16 }
 17 
 18 int to_upper(int c)
 19 {
 20     if(isupper(c))
 21     {
 22         return (c-32);
 23     }
 24     return c;
 25 }
 26 
 27 int main()
 28 {
 29     // 初始化string
 30     string s1="ACM";
 31 
 32     string s2("ACM");
 33 
 34     string s3=s2;
 35 
 36     //string s4(10,"ACM");
 37     string s4(10,'A');
 38     // 第四种初始化方式,只能初始化单个字符
 39 
 40     cout<<s1<<endl;
 41     cout<<s2<<endl;
 42     cout<<s3<<endl;
 43     cout<<s4<<endl;
 44 
 45 
 46     cout<<"数组方式遍历:"<<endl;
 47     // 遍历string
 48     for(int i=0;i<=s1.length()+4;++i)
 49     {
 50         cout<<s1[i];
 51     }
 52     cout<<endl;
 53     // 用数组方式遍历,越界时,不会发生错误,不会抛出异常
 54 
 55 
 56     cout<<"at:"<<endl;
 57     // at方式遍历
 58     for(int i=0;i<s1.length();++i)
 59     {
 60         cout<<s1.at(i);
 61     }
 62     cout<<endl;
 63     // 抛出异常
 64     // 将上述循环中,循环终止条件小于改为小于等于异常如下:
 65     // ACM 烐GACMterminate called after throwing an instance of 'std::out_of_range'
 66     //what():  basic_string::at
 67 
 68 
 69     // 迭代器遍历
 70     cout<<"迭代器遍历:"<<endl;
 71     for(string::iterator it=s1.begin();it!=s1.end();++it)
 72     {
 73         cout<<*it;
 74     }
 75     cout<<endl;
 76     // 上述string::iterator迭代器可以看作是一个字符指针
 77     // 注意,s1.end()不是指向字符的最后一个位置,而是指向字符最后一个位置后面的一个位置
 78 
 79 
 80 
 81     // C_str 将string转化为const char *
 82     //char *p=s1.c_str();
 83     // 以上代码报错如下
 84     //F:\acm\训练日记\2020.1.27\program\t15.cpp|62|error: invalid conversion from 'const char*' to 'char*' [-fpermissive]|
 85     // 可见c_str()将string类型转化为了const char *
 86     const char *s=s1.c_str();
 87     cout<<endl<<"s:"<<endl;
 88     cout<<s<<endl<<endl;
 89     // 可以直接用const char *赋值给string
 90     string s5=s;
 91     cout<<"s5:"<<endl;
 92     cout<<s5<<endl;
 93     // 也可以直接用char *赋值给string类型,方便好用
 94     char *p="heiheihaha";
 95     string s6=p;
 96     cout<<"s6:"<<s6<<endl;
 97     // 其实这也是属于上述构造构造函数的范畴
 98 
 99 
100     // copy(buf,size,begin) 将begin开始的size个字符,拷贝到buf中,不会在buf的末尾,加额外的'\0'
101     // 注意越界问题,越界不会抛出异常
102     char buf[100];
103     s1.copy(buf,3,0);
104     cout<<"buf"<<endl;
105     cout<<buf<<endl;
106     //string buf2;
107     //s1.copy(buf2,2,0);
108     //cout<<"buf2:"<<buf2<<endl;
109     // 以上代码是错误的,buf必须为char*类型,不能是string类型
110 
111     // 如下方法拼接,不改变s1
112     string s7=s1+s2;
113     cout<<"s1: "<<s1<<endl;
114     cout<<"s2: "<<s2<<endl;
115     cout<<"s7: "<<s7<<endl;
116     cout<<endl;
117 
118     // 如下方法拼接,已改变s1
119     string s8=s1.append(s2);
120     cout<<"s1:"<<s1<<endl;
121     cout<<"s2:"<<s2<<endl;
122     cout<<"s8:"<<s8<<endl;
123     cout<<endl;
124 
125     // 如不想改变的话,也可以
126     string s9;
127     s9.append(s1);
128     s9.append(s2);
129     cout<<"s1:"<<s1<<endl;
130     cout<<"s2:"<<s2<<endl;
131     cout<<"s9:"<<s9<<endl;
132     cout<<endl;
133 
134 
135     // find
136     int index=s1.find("ACM");
137     cout<<index<<endl;
138     // 第二个参数不写,默认为0
139     cout<<s1.find("ACM",0)<<endl;
140     cout<<s1.find("ACM",1)<<endl;
141     // 返回第二个ACM出现的位置
142 
143     cout<<s9<<endl;
144     // 返回第一次出现ACM的首字符A的位置
145     cout<<s9.find_first_of("ACM")<<endl;
146     // 返回最后一次出现ACM的末尾字符M的位置
147     cout<<s9.find_last_of("ACM")<<endl;
148     // 以上下标,都是从0开始的
149 
150     // 如果没有找到会返回什么呢?
151     size_t num=string::npos;
152     int num1=num;
153     cout<<s9.find("ACMER")<<endl;
154     cout<<string::npos<<endl;
155     cout<<num<<endl;
156     // 你可能很奇怪上述输出的值,让我们看看用int类型来输出
157     cout<<num1<<endl;
158     unsigned int num2=num;
159     cout<<num2<<endl;
160     // 实际上,这是个-1
161     // 只是因为用了较大范围的类型(不准确,其实范围一样,只是将负数部分正数编码了),才变成了那个很大的值
162 
163 
164     // 试试将字符串中某一字符串替换成另一字符串
165     cout<<"s9:"<<s9<<endl;
166     int cur_index=s9.find("ACM");
167     while(cur_index != string::npos)
168     {
169         s9.replace(cur_index,strlen("ACM"),"ACMER");    // 注意strlen函数要有头文件cstring
170         // 这一步保证了如果新字符串中存在当前字符时,不会重复替换,甚至陷入死循环
171         // 从已经被替换的字符串后面开始
172         cur_index+=strlen("ACMER");
173         cur_index=s9.find("ACM",cur_index);
174     }
175     cout<<"s9:"<<s9<<endl;
176     // replace,第一个参数为起始位置,第二个参数为要替换的字符串有多少个字符,第三个参数为新字符串
177 
178 
179     // 最后,是插入和删除操作
180 
181     cout<<"s1:"<<s1<<endl;
182     //string::iterator it=find(s1.begin(),s1.end(),'a');
183     //F:\acm\训练日记\2020.1.27\program\t15.cpp|163|error: no matching function for call to 'find(std::basic_string<char>::iterator, std::basic_string<char>::iterator, char)'|
184     // 网上的一些字符串函数,我这里好像不能用
185     // 暂时不知道原因,留作疑问,继续深入学习
186     //cout<<*it<<endl;
187     s1.erase(s1.begin(),s1.begin()+3);
188     cout<<s1<<endl;
189     s1.insert(0,"ACMER");
190     cout<<s1<<endl;
191 
192 
193     // 大小写转换
194     transform(s1.begin(),s1.end(),s1.begin(),to_lower);
195     cout<<s1<<endl;
196     transform(s1.begin(),s1.end(),s1.begin(),to_upper);
197     cout<<s1<<endl;
198     // 嗯?原来还要自己写to_lower和to_upper吗?
199     // 可能为了灵活些
200     // 毕竟是transfor,转化是任意的,大家可以多尝试尝试
201     // string的基本内容,大概就这么多了,学一下,之后用起来方便点
202 
203     return 0;
204 }
205 
206 // 本机执行结果如下,由于前面尝试越界,比较危险,可能引发各种问题
207 // 不过问题不大
208 /*
209 ACM
210 ACM
211 ACM
212 AAAAAAAAAA
213 数组方式遍历:
214 ACM 狍颈
215 at:
216 ACM
217 迭代器遍历:
218 ACM
219 
220 s:
221 ACM
222 
223 s5:
224 ACM
225 s6:heiheihaha
226 buf
227 ACM
228 s1: ACM
229 s2: ACM
230 s7: ACMACM
231 
232 s1:ACMACM
233 s2:ACM
234 s8:ACMACM
235 
236 s1:ACMACM
237 s2:ACM
238 s9:ACMACMACM
239 
240 0
241 0
242 3
243 ACMACMACM
244 0
245 8
246 4294967295
247 4294967295
248 4294967295
249 -1
250 4294967295
251 s9:ACMACMACM
252 s9:ACMERACMERACMER
253 s1:ACMACM
254 ACM
255 ACMERACM
256 acmeracm
257 acmeracm
258 
259 Process returned 0 (0x0)   execution time : 0.608 s
260 Press any key to continue.
261 */

 

posted on 2020-01-28 11:53  带你AK,带你飞  阅读(238)  评论(0编辑  收藏  举报