字符串的處理一直是一個熱門話題。
在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 = "[email protected]";
if (check_email(email) == -1){
cout << "the inputed email error!" << endl;
return -1;
}
cout << "the inputed email correct!" << endl;
return 0;
}