字符串的处理一直是一个热门话题。
在C中,字符串是不存在的。我们用字符数组和字符指针模拟字符串。
在C++ STL中,我们有了真正的字符串。实际上,C++ stl中的字符串是对传统C中的字符串的封装。新瓶装旧酒。
我们接下来讲一下几个部分:
- string和C风格字符串的互换。
- string字符串的初始化
- string字符串的赋值
- string字符串元素的存取
- string字符串的操作
- string字符串的拼接
- string字符串的查找
- string字符串的替换
- string字符串分割子串
- string字符串的删除
- string字符串的插入
- string字符串的比较
Here we go!
- string和C风格字符串的转换
string s1="abcd";
char *str1="1234";
const char * str2=s1.c_str();
string s2(str1);
cout<<str2<<endl;
cout<<s2<<endl;
- string字符串初始化(构造函数)
string s1; //默认构造函数
string s2(10,'a'); //带参数的构造函数
string s3(s2); //拷贝构造函数
string s4=s3; //运算符重载
- string字符串的赋值
string s1;
//运算符=重载,赋值
s1="abcd";
//调用字符串方法.assign()
string s2;
s2.assign(s1); //等价于s2.assign("abcd");
string s3;
s3.assign(10,'b');
cout<<s1<<endl;
cout<<s2<,endl;
cout<<s3<<endl;
字符串元素的存取
容器利用迭代器访问容器中的元素。当容器没有迭代器时,不能利用下标法访问容器中的元素。string s1="abcd"; for(int i=0;i<s1.size();i++){ cout<<s1[i]<<endl; } for(int j=0;j<s1.size();j++){ cout<<s1.at(j)<<endl; }
这里要注意[i]和.at(i)的区别。使用[i],当i越界时,程序直接崩溃。使用.at(i)当i越界时,程序会抛出异常。
s2="abcd"; try{ //s2[99]; s2.at(99); } catch (...){ cout << "s2 does have the element in the position 99" << endl; }
- 字符串的拼接
string s1="123";
string s2="abc";
string s3=s1+s2;
s1.append(s2);
cout<<s3<<endl;
cout<<s1<<endl;
- 字符串的查找
string s1="abcdabcd";
string target="ab";
int retn1 = s1.find(target); //正向查找,并返回所查找字符串的首元素index
int retn2 = s1.rfind(target); //反向查找,并返回所查找字符串的首元素index
cout<<retn1<<" "<<retn2<<endl;
- 字符串的替换
string s1 = "abcdef";
string target = "123";
s1.replace(2, 2, target); //start_pos num str
cout << s1 << endl; //ab123ef
- 字符串的分割子串
string s1="abcdefg";
//我们想取出字符串s1中的子串def
string s2 = s1.substr(3,3); // start_pos num
cout<<s2<<endl;
- 字符串删除
string s1="abcdefghijk";
//我们想删除子串defg
s1.erase(3,4);
cout<<s1<<endl;
- 字符串插入
string s1="12345678";
string target = "abc";
//我们想在4和5之间插入字符串abc。插入是将index位置及之后的元素向后移动,然后将所插入ele放在index位置。
s1.insert(4,target);
cout<<s1<<endl;
//我们想在字符串末尾插入abc
s1.insert(s1.size(),target); //s1.size()返回字符串s1中的元素个数,s1[s1.size()]位置为'\0'
cout<<s1<<endl;
- 字符串的比较
string s1 = "abcdefg";
string s2 = "abcdq";
int ret = s1.compare(s2);
if (ret == 1) cout << "s1 is bigger than s2 " << endl;
else if (ret == -1) cout << "s1 is less than s2" << endl;
else cout<< "s1 is equal to s2" << endl;
- 字符串的应用:邮箱验证
写了一个很简单的demo。主要完成了一下三个功能:
- 判断邮箱的有效性。 (是否含有@和.,并且@在.之前)
- 判断用户输入的邮箱名是否满足规则(这里的规则是,邮箱名是否全部由小写字母构成)
- 判断用户输入的邮箱域名是否正确(这里的域名有gmail hotmail ncsu)
由此demo,我们可以扩展出更完善和健壮的功能。这里主要是想锻炼一下用C++STL处理string的能力。
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int check_validation(string &email,int *pos1,int *pos2){
int pos1_temp = email.find("@");
int pos2_temp = email.find(".");
//cout << pos1_temp << pos2_temp << endl;
if ((pos1_temp == -1) || (pos2_temp == -1) || (pos1_temp > pos2_temp)){
cout << "validation error!" << endl;
return -1;
}
*pos1 = pos1_temp;
*pos2 = pos2_temp;
return 0;
}
int check_username(string &email,int pos1){
string usrname = email.substr(0, pos1);
string::iterator pStart = usrname.begin();
string::iterator pEnd = usrname.end();
while (pStart != pEnd){
if ((*pStart > 122 || *pStart < 97) && (*pStart<65 || *pStart>90) && (*pStart<0 || *pStart>9)){
cout << "username invalidation!" << endl;
return -1;
}
pStart++;
}
return 0;
}
int check_hostname(string &email, int pos1,int pos2){
string hostname = email.substr(pos1+1, pos2 - pos1-1);
bool flag;
flag = hostname.compare("gmail")*hostname.compare("hotmail")*hostname.compare("ncsu");
if (flag){
cout << "hostname error!" << endl;
return -1;
}
}
int check_email(string &email){
int pos1 = 0;
int pos2 = 0;
if (check_validation(email, &pos1, &pos2) == -1) return -1;
if (check_username(email, pos1) == -1) return -1;
if (check_hostname(email, pos1, pos2) == -1) return -1;
return 0;
}
int main(){
string email = "zhaosi@shu.com";
if (check_email(email) == -1){
cout << "the inputed email error!" << endl;
return -1;
}
cout << "the inputed email correct!" << endl;
return 0;
}