std::string的工具函式
一般來說,在處理字串的時候通常會用到如下一些函式/方法:length、substring、find、charAt、toLowerCase、toUpperCase、trim、equalsIgnoreCase、startsWith、endsWith、parseInt、toString、split等。
如果使用STL中的std::string,它已經提供瞭如下一些比較有用的方法:
length(),取得字串的長度。
substr(),從字串中取出一個子串。
at()/operator [],取得字串中指定位置的字元。
find/rfind(),從前往後/從後往前在字串中查詢一個子串的位置。
find_first_of(),在字串中找到第一個在指定字符集中的字元位置。
find_first_not_of(),在字串中找到第一次人不在指定字符集中的字元位置。
find_last_of(),在字串中找到最後一個在指定字符集中的字元位置。
find_last_not_of(),在字串中找到最後一個不在字符集中的字元位置。
關於std::string的其它方法,請參閱它的文件(在MSDN中可以找到)。
很容易發現,std::string並沒有提供所有需要方法。所以,需要用STL提供了演算法庫、字串流以及現存的std::string的方法來實現它們。
※ 將字串轉換為大寫/小寫
std::transform(str.begin(), str.end(), str.begin(), toupper);
※ 去掉字串兩端的空格
1) 去掉左邊的空格
2) 去掉右邊的空格
3) 去掉兩邊的空格
※ 忽略大小寫比較字串
這一功能的實現比較簡單,只需要先將用於比較的兩個字串各自拷貝一個複本,並將這兩個複本轉換為小寫,然後比較轉換為小寫之後的兩個字串即可。
※ StartsWith和EndsWith
1) StartsWith
如果返回值為true,則str是以substr開始的
2) EndsWith
如果返回值為true,則str是以substr結束的
還有另一個方法可以實現這兩個函式。就是將str從頭/尾擷取substr長度的子串,再將這個子串也substr進行比較。不過這種方法需要判斷str的長度是否足夠,所以建議用find和rfind來實現。
※ 從字串解析出int和bool等型別的值
說到將字串解析成int,首先想到的一定是atoi、atol等C函式。如果用C++來完成這些工具函式,那就要用到std::istringstream。
除了解析bool值之外,下面這個函式可以解析大部分的型別的數值:
T value;
std::istringstream iss(str);
iss >> value;
return value;
}
上面這個模板可以將0解析成bool值false,將非0解析成treu。但它不能將字串”false”解析成false,將”true”解析成true。因此要用一個特別的函式來解析bool型的值:
bool parseString(const std::string& str) {
bool value;
std::istringstream iss(str);
iss >> boolalpha >> value;
return value;
}
上面的函式中,向輸入流傳入一個std::boolalpha標記,輸入流就能認識字元形式的”true”和”false”了。
使用與之類似的辦法解析十六進位制字串,需要傳入的標記是std::hex:
T value;
std::istringstream iss(str);
iss >> hex >> value;
return value;
}
※ 將各種數值型別轉換成字串(toString)
與解析字串類似,使用std::ostringstream來將各種數值型別的數值轉換成字串,與上面對應的3個函式如下:
std::ostringstream oss;
oss << value;
return oss.str();
}
string toString(const bool& value) {
ostringstream oss;
oss << boolalpha << value;
return oss.str();
}
template<class T> std::string toHexString(const T& value, int width) {
std::ostringstream oss;
oss << hex;
if (width > 0) {
oss << setw(width) << setfill(`0`);
}
oss << value;
return oss.str();
}
注意到上面函式中用到的setw和setfill沒有?它們也是一種標記,使用的時候需要一個引數。std::setw規定了向流輸出的內容佔用的寬度,如果輸出內容的寬度不夠,預設就用空格填位。std::setfill則是用來設定佔位符。如果還需要控制輸出內容的對齊方式,可以使用std::left和std::right來實現。
※ 拆分字串和Tokenizer
拆分字串恐怕得用Tokenizer來實現。C提供了strtok來實現Tokenizer,在STL中,用std::string的find_first_of和find_first_not_of來實現。下面就是Tokenizer類的nextToken方法:
// find the start character of the next token.
size_t i = m_String.find_first_not_of(delimiters, m_Offset);
if (i == string::npos) {
m_Offset = m_String.length();
return false;
}
// find the end of the token.
size_t j = m_String.find_first_of(delimiters, i);
if (j == string::npos) {
m_Token = m_String.substr(i);
m_Offset = m_String.length();
return true;
}
// to intercept the token and save current position
m_Token = m_String.substr(i, j – i);
m_Offset = j;
return true;
}
※ 原始碼
最後,關於上述的一些方法,都已經實現在strutil.h和strutil.cpp中,所以現在附上這兩個檔案的內容:
√Header file: strutil.h
//
// Utilities for std::string
// defined in namespace strutil
// by James Fancy
//
////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <string>
#include <vector>
#include <sstream>
#include <iomanip>
// declaration
namespace strutil {
std::string trimLeft(const std::string& str);
std::string trimRight(const std::string& str);
std::string trim(const std::string& str);
std::string toLower(const std::string& str);
std::string toUpper(const std::string& str);
bool startsWith(const std::string& str, const std::string& substr);
bool endsWith(const std::string& str, const std::string& substr);
bool equalsIgnoreCase(const std::string& str1, const std::string& str2);
template<class T> T parseString(const std::string& str);
template<class T> T parseHexString(const std::string& str);
template<bool> bool parseString(const std::string& str);
template<class T> std::string toString(const T& value);
template<class T> std::string toHexString(const T& value, int width = 0);
std::string toString(const bool& value);
std::vector<std::string> split(const std::string& str, const std::string& delimiters);
}
// Tokenizer class
namespace strutil {
class Tokenizer
{
public:
static const std::string DEFAULT_DELIMITERS;
Tokenizer(const std::string& str);
Tokenizer(const std::string& str, const std::string& delimiters);
bool nextToken();
bool nextToken(const std::string& delimiters);
const std::string getToken() const;
/**
* to reset the tokenizer. After reset it, the tokenizer can get
* the tokens from the first token.
*/
void reset();
protected:
size_t m_Offset;
const std::string m_String;
std::string m_Token;
std::string m_Delimiters;
};
}
// implementation of template functions
namespace strutil {
template<class T> T parseString(const std::string& str) {
T value;
std::istringstream iss(str);
iss >> value;
return value;
}
template<class T> T parseHexString(const std::string& str) {
T value;
std::istringstream iss(str);
iss >> hex >> value;
return value;
}
template<class T> std::string toString(const T& value) {
std::ostringstream oss;
oss << value;
return oss.str();
}
template<class T> std::string toHexString(const T& value, int width) {
std::ostringstream oss;
oss << hex;
if (width > 0) {
oss << setw(width) << setfill(`0`);
}
oss << value;
return oss.str();
}
}
√Source file: strutil.cpp
//
// Utilities for std::string
// defined in namespace strutil
// by James Fancy
//
////////////////////////////////////////////////////////////////////////////////
#include “strutil.h“
#include <algorithm>
namespace strutil {
using namespace std;
string trimLeft(const string& str) {
string t = str;
t.erase(0, t.find_first_not_of(“ /t/n/r“));
return t;
}
string trimRight(const string& str) {
string t = str;
t.erase(t.find_last_not_of(“ /t/n/r“) + 1);
return t;
}
string trim(const string& str) {
string t = str;
t.erase(0, t.find_first_not_of(“ /t/n/r“));
t.erase(t.find_last_not_of(“ /t/n/r“) + 1);
return t;
}
string toLower(const string& str) {
string t = str;
transform(t.begin(), t.end(), t.begin(), tolower);
return t;
}
string toUpper(const string& str) {
string t = str;
transform(t.begin(), t.end(), t.begin(), toupper);
return t;
}
bool startsWith(const string& str, const string& substr) {
return str.find(substr) == 0;
}
bool endsWith(const string& str, const string& substr) {
return str.rfind(substr) == (str.length() – substr.length());
}
bool equalsIgnoreCase(const string& str1, const string& str2) {
return toLower(str1) == toLower(str2);
}
template<bool>
bool parseString(const std::string& str) {
bool value;
std::istringstream iss(str);
iss >> boolalpha >> value;
return value;
}
string toString(const bool& value) {
ostringstream oss;
oss << boolalpha << value;
return oss.str();
}
vector<string> split(const string& str, const string& delimiters) {
vector<string> ss;
Tokenizer tokenizer(str, delimiters);
while (tokenizer.nextToken()) {
ss.push_back(tokenizer.getToken());
}
return ss;
}
}
namespace strutil {
const string Tokenizer::DEFAULT_DELIMITERS(“ “);
Tokenizer::Tokenizer(const std::string& str)
: m_String(str), m_Offset(0), m_Delimiters(DEFAULT_DELIMITERS) {}
Tokenizer::Tokenizer(const std::string& str, const std::string& delimiters)
: m_String(str), m_Offset(0), m_Delimiters(delimiters) {}
bool Tokenizer::nextToken() {
return nextToken(m_Delimiters);
}
bool Tokenizer::nextToken(const std::string& delimiters) {
// find the start charater of the next token.
size_t i = m_String.find_first_not_of(delimiters, m_Offset);
if (i == string::npos) {
m_Offset = m_String.length();
return false;
}
// find the end of the token.
size_t j = m_String.find_first_of(delimiters, i);
if (j == string::npos) {
m_Token = m_String.substr(i);
m_Offset = m_String.length();
return true;
}
// to intercept the token and save current position
m_Token = m_String.substr(i, j – i);
m_Offset = j;
return true;
}
const string Tokenizer::getToken() const {
return m_Token;
}
void Tokenizer::reset() {
m_Offset = 0;
}
}
本文轉自邊城__ 51CTO部落格,原文連結:http://blog.51cto.com/jamesfancy/843209,如需轉載請自行聯絡原作者
相關文章
- std::count 函式函式
- string 函式的基本用法函式
- php操作string的函式PHP函式
- std::string的find問題研究
- string 函式彙總函式
- string型別資料的find函式型別函式
- PHP 每日一函式 — 字串函式 convert_cyr_string ()PHP函式字串
- C++11中std::move、std::forward、左右值引用、移動建構函式的測試C++Forward函式
- PHP之string之ord()函式使用PHP函式
- String型別函式傳遞問題型別函式
- Python 字串 String 內建函式大全(1)Python字串函式
- Python 字串 String 內建函式大全(2)Python字串函式
- Folly解讀(零) Fbstring—— 一個完美替代std::string的庫
- PHP之string之str_split()函式使用PHP函式
- PHP之string之str_pad()函式使用PHP函式
- string.h標頭檔案(字串函式)字串函式
- 左值、右值、左值引用,右值引用,std::move函式函式
- 雖然包含string標頭檔案但未用std::
- Vue 原始碼中的工具函式Vue原始碼函式
- 【C++】【原始碼解讀】std::is_same函式原始碼解讀C++原始碼函式
- JavaScript 工具函式大全(新)JavaScript函式
- 讓你事半功倍的JS utils工具函式JS函式
- python函式教程:Python 字串操作(string替換、擷取等)Python函式字串
- 10個必備的 async/await 工具函式AI函式
- Rxjs 裡 subscribeToArray 工具函式的詳細分析JS函式
- std::reserve和std::resize的區別
- main函式的入口函式AI函式
- 對”在嵌入式Rust中使用std“的看法Rust
- 讀 zepto 原始碼之工具函式原始碼函式
- JavaScript工具函式助力高效開發JavaScript函式
- 前端常用的工具類函式, 持續更新中前端函式
- 關於Vue中常用的工具函式封裝Vue函式封裝
- `std::packaged_task`、`std::thread` 和 `std::async` 的區別與聯絡Packagethread
- 函式FUN_GET_SPOOL_STRING_LHR的內容--spool匯出csv檔案格式函式
- 工作學習筆記(一) StringUtils.split()和string.split()函式的區別筆記函式
- Golang工具集-String工具,時間工具,http工具等GolangHTTP
- JS開發常用工具函式JS函式
- 【vue】自定義一個websocket工具函式VueWeb函式
- 箭頭函式、簡寫函式、普通函式的區別函式