如何處理字串(C++11)
C++對於字串的處理已經很方便、很高階了(跟C相比)
只是要用對方法
字串處理起來的舒暢程度我認為不輸Java
而我所用的方法其實說穿了就是C++的標準函式庫(STL)
以下是我們在處理字串時會用到三個東西,分別是兩個Class和一個function
第一個是std::string,這裡是std::string相關的C++ Reference頁面
第二個是std::stringstream,這裡是std::stringstream相關的C++ Reference頁面
最後是std::getline,這裡是std::getline相關的C++ Reference頁面
[目錄]
概論:該如何安全地處理字串
字串相關的宣告與初值化:std::string、std::stringstream
字串的讀取、切割字串
字串的常用操作:拼接、尋找、刪除、插入、加長、相等比較、取代
字串的型態轉換
[概論:該如何安全地處理字串]
好了,今天的筆記到此結束
只是要用對方法
字串處理起來的舒暢程度我認為不輸Java
而我所用的方法其實說穿了就是C++的標準函式庫(STL)
以下是我們在處理字串時會用到三個東西,分別是兩個Class和一個function
第一個是std::string,這裡是std::string相關的C++ Reference頁面
第二個是std::stringstream,這裡是std::stringstream相關的C++ Reference頁面
最後是std::getline,這裡是std::getline相關的C++ Reference頁面
[目錄]
概論:該如何安全地處理字串
字串相關的宣告與初值化:std::string、std::stringstream
字串的讀取、切割字串
字串的常用操作:拼接、尋找、刪除、插入、加長、相等比較、取代
字串的型態轉換
[概論:該如何安全地處理字串]
1.所有變數皆用std::string,不用任何char*或char[]
2.任何型態的變數都先丟進std::stringstream,再丟出來變成切好的std::string來做
所有我們想做的字串處理(尋找,拼接,相等比較等等)
很多時候其實我們只需要切字串,所以std::stringstream丟出來之後就搞定了
3.做完處理的字串,除了幾個方便簡短的轉換函數可以記一下以外
若要做型態轉換的話,就都再丟一次std::stringstream
它出來可以指派給任何資料型態的變數
4.用std::vector儲存需要存的std::string
要注意的是,用我所說的方法
可以確保程式是安全的、簡潔的,而且寫起來是順暢的
但速度並沒有用C或是其他較低階的函數操作來得快
2.任何型態的變數都先丟進std::stringstream,再丟出來變成切好的std::string來做
所有我們想做的字串處理(尋找,拼接,相等比較等等)
很多時候其實我們只需要切字串,所以std::stringstream丟出來之後就搞定了
3.做完處理的字串,除了幾個方便簡短的轉換函數可以記一下以外
若要做型態轉換的話,就都再丟一次std::stringstream
它出來可以指派給任何資料型態的變數
4.用std::vector儲存需要存的std::string
要注意的是,用我所說的方法
可以確保程式是安全的、簡潔的,而且寫起來是順暢的
但速度並沒有用C或是其他較低階的函數操作來得快
[字串相關的宣告與初值化:std::string、std::stringstream]
先看std::stringstream的宣告
先看std::stringstream的宣告
//stringstream_test.cpp
#include <iostream>
#include <string>
#include <sstream>
int main(){
std::stringstream ss1("hello"); //often used
std::stringstream ss2, ss3, ss4, ss5;
ss2.str("haha");
std::string str_hey = "hey";
ss3.str(str_hey);
ss4 << "cool";
ss5 << str_hey;
std::cout << "ss1: " << ss1 << std::endl;
<< "ss1.str(): " << ss1.str() << std::endl
<< "ss2.str(): " << ss2.str() << std::endl
<< "ss3.str(): " << ss3.str() << std::endl
<< "ss4.str(): " << ss4.str() << std::endl
<< "ss5.str(): " << ss5.str() << std::endl;
}
result :
這裡比較值得一提的是如果是 ss4 << "so" << "cool" << std::endl;的話
他的效果會等同於先做 ss4 << "so",接著ss4 << "cool",最後ss4 << std::endl;
就像我們習以為常的std::cout << 一樣
他的效果會等同於先做 ss4 << "so",接著ss4 << "cool",最後ss4 << std::endl;
就像我們習以為常的std::cout << 一樣
接著看std::string的宣告,這太基本了我快速帶過
//stringstream_test.cpp
#include <iostream>
#include <string>
#include <sstream>
int main(){
std::string str1 = "hello";
std::string str2("hi");
std::string str3 = ""; //often used
str3 = "hey";
std::cout << "str1: " << str1 << std::endl
<< "str2: " << str2 << std::endl
<< "str3: " << str3 << std::endl;
/*result:
str1: hello
str2: hi
str3: hey
*/
}
[字串的讀取、切割字串]
這裡的讀取是指從std::strinstream中取出std::string
切割字串主要有兩種方式
1. 直接從std::stringstream取出std::string。此方法用任意空白做切割
2. 用std::getline()把std::stringstrem用特別的std::string做斷句取出。
此種方法可以指定特定的字串做切割,但若沒指定則不會切割空白
先展示如何從std::stringstream讀取std::string
//stringstream_test.cpp
#include <iostream>
#include <string>
#include <sstream>
int main(){
std::stringstream ss("a long. string!!");
std::string str1, str2, str3, str4;
ss >> str1; //a
ss >> str2; //long.
ss >> str3; //string!!
ss >> str4; //ss is empty
std::cout << "ss.str(): " << ss.str() << std::endl
<< "str1: " << str1 << std::endl
<< "str2: " << str2 << std::endl
<< "str3: " << str3 << std::endl
<< "str4: " << str4 << std::endl
<< "ss >> str4: " << (ss >> str4) << std::endl;
}
result:
這裡有兩個事情需要注意
1. 當std::stringstream已經讀完(讀取的位置已經到最後了),再讀都只能得到空白
而且這個讀取的動作會返回一個0的值,可用於迴圈對於讀取完畢的判斷
2. 是如果已經讀完,又讀了空白的話(非空格),此時讀取位置會設成-1
此時無法用ss.seekg(0)來設定讀取位置,只能用ss.clear()清除資料後重新來過
否則此std::stringstream將再也讀不出資料來
接著來看切割字串,一共兩招
第一招就只是剛才的程式碼加上迴圈而已
1. 直接從std::stringstream取出std::string。此方法用任意空白做切割
//stringstream_test.cpp
#include <iostream>
#include <string>
#include <sstream>
int main(){
std::stringstream ss("a long. string!!");
std::string str = "";
while(ss >> str){
std::cout << str << std::endl;
}
}
result:
2. 用std::getline()把std::stringstrem用特別的std::string做斷句取出。
//stringstream_test.cpp
#include <iostream>
#include <string>
#include <sstream>
int main(){
std::stringstream ss("a long. string!!");
std::string str = "";
while(std::getline(ss,str,'n')){
std::cout << str << std::endl;
}
}
result:
這裡要注意的是
第三個argument只能放char,不能放std::string
[字串的常用操作:拼接、尋找、刪除、插入、加長、相等比較、取代]
這太基本了我快速帶過
//stringstream_test.cpp
#include <iostream>
#include <string>
#include <sstream>
int main(){
std::string str = "Hello world";
//mix
std::string str1 = "I'm Burwei!!";
str1 = str + ". " + str1;
std::cout << str1 << std::endl; //result: Hello world. I'm Burwei!!
//find
std::cout << str.find("l") << std::endl; //result: 2
std::cout << str.find("l",0) << std::endl; //result: 2
//erase
std::string str2 = str; //Hello world
std::cout << str2.erase(2,2) << std::endl; //result: Heo world
//insert
std::string str3 = str; //Hello world
std::cout << str3.insert(3,"HAHA") << std::endl;//result: HelHAHAlo world
//append
std::string str4 = str; //Hello world
std::cout << str4.append("HAHA") << std::endl; //result: Hello worldHAHA
//replace
std::string str5 = str; //Hello world
std::string token_old = "l";
std::string token_new = "LLL";
int pos = 0;
while((pos = str5.find(token_old,pos)) != std::string::npos) {
str5.replace(pos, token_old.length(),token_new);
}
std::cout << str5 << std::endl; //result: HeLLLLLLo worLLLd
//compare
if(str==str1)
std::cout << "str==str1" << std::endl;
else
std::cout << "str!=str1" << std::endl; //result: str!=str1
}
[字串的型態轉換]
最後,展示一下用std::stringstream做型態轉換
//stringstream_test.cpp
#include <iostream>
#include <string>
#include <sstream>
int main(){
std::stringstream ss1, ss2;
ss1 << "1234" << 1.234 << "cool";
ss2 << "1234" << " " << 1.234 << " " << " cool";
float a, b, c, d;
char ch1[100] = {0};
char ch2[100] = {0};
ss1 >> a >> b >> ch1;
ss2 >> c >> d >> ch2;
std::cout << std::setprecision(8)
<< "a+b: " << a+b << std::endl
<< "a: " << a << " / b: " << b << std::endl
<< "ch1: " << ch1 << std::endl
<< "c+d: " << c+d << std::endl
<< "c: " << c << " / d: " << d << std::endl
<< "ch2: " << ch2 << std::endl;
}
result:好了,今天的筆記到此結束
留言
張貼留言