去年也就是2021年千萬人氣部落客高雄達人大叔寫了C# Substring 定義及七種用法,這篇關於c# substring的探討躍升至Google排行第二名,還頗讓人驚訝的,文中也提到這是起源自c substr的用法的探討,這篇到現在也是在Google的排行第二名,文中也順便提到了有關c++ substr的使用可以參考C++全方位學習第四版(適用Dev C++與Visual C++),但看起來還是有人會來那裡看C++的東西,索性今年就來個C++ substr的探討吧,雖然我已經很久沒玩C++了,我一直在看看工作達人上哪種程式語言會是我最終使用的程式語言,對我而言,造訪自己的部落格已經變成了一種儀式,一種神聖的習慣,我希望除了可以幫助我自己外,也可以幫助所有對未來工作有所疑惑的華人有幫助。
因為我一直是使用微軟的Visual Studio 2017開發,以下很多資料引用自微軟的文件庫,不過文章是機器翻譯的,過幾天如果看不習慣,就會修改一下,朋友有什麼建議的也可以留言告知。
子字串(substring)的操作:
因字串(string)是在std命名空間中,故要在C++中使用,需先在開頭寫下:
using namespace std;
using std::string;
1.c++ substr 取得子字串
定義
basic_string<CharType, Traits, Allocator> substr( size_type offset = 0, size_type count = npos) const;
從開始於指定位置的字串,複製最多一定字元數量的子字串。
參數
offset
索引,用於將元素定位在建立字串複本的來源位置,預設值為 0。
count
要複製的字元數(如果有的話)。
傳回值
從第一個引數所指定的位置開始的子字串物件,它是字串運算元的元素複本。
異常
若 offset > size()
則為 std::out_of_range 。
複雜度
與 n 成線性。
範例
下面範例是利用substr函數取得s1的部份字串,例如s2=s1.substr(6,5) 是取得s1的6~10字元(world)存入s2字串。
string s1(“Hello World!”),s2;
s2=s1.substr(6,5) ; //s2 = world
補充說明:
因字串(string)是在std命名空間中,故要在C++中使用,需先在開頭寫下:
using namespace std;
using std::string;
string a=”123456789″;
cout<<a.substr(2,5)<<endl; //表示呼叫「字串a索引2數起的5個字元」所構成的子字串,顯示34567
cout<<a.substr(2)<<endl; //表示呼叫「字串a索引2數起之後的所有字元」所構成的子字串,顯示3456789
2.c++ append 將字元加入至字串的結尾
定義
basic_string<CharType, Traits, Allocator>& append( const value_type* ptr);
basic_string<CharType, Traits, Allocator>& append( const value_type* ptr, size_type count);
basic_string<CharType, Traits, Allocator>& append( const basic_string<CharType, Traits, Allocator>& str, size_type offset, size_type count);
basic_string<CharType, Traits, Allocator>& append( const basic_string<CharType, Traits, Allocator>& str);
basic_string<CharType, Traits, Allocator>& append( size_type count, value_type char_value);
template <class InputIterator> basic_string<CharType, Traits, Allocator>& append( InputIterator first, InputIterator last);
basic_string<CharType, Traits, Allocator>& append( const_pointer first, const_pointer last);
basic_string<CharType, Traits, Allocator>& append( const_iterator first, const_iterator last);
參數
ptr
要附加的 C 字串。
str
要附加其字元的字串。
offset
提供要附加之字元的部分來源字串組件的索引。
count
要從來源字串附加的字元數上限。
char_value
要附加的字元值。
first
輸入迭代器,為範圍中要附加的第一個元素定址。
last
輸入反覆運算器、 const_pointer
或 const_iterator
定址範圍中要附加之最後一個元素之後的位置。
傳回值
正在附加成員函式所傳遞字元之字串物件的參考。
備註
您可以使用或成員函式或,將字元附加至字串 operator+=
append
push_back
。 operator+=
附加單一引數值,而多重引數成員函式則 append
允許指定字串的特定部分以供加入。
範例
// basic_string_append.cpp // compile with: /EHsc #include <string> #include <iostream> int main( ) { using namespace std; // The first member function // appending a C-string to a string string str1a ( "Hello " ); cout << "The original string str1 is: " << str1a << endl; const char *cstr1a = "Out There "; cout << "The C-string cstr1a is: " << cstr1a << endl; str1a.append ( cstr1a ); cout << "Appending the C-string cstr1a to string str1 gives: " << str1a << "." << endl << endl; // The second member function // appending part of a C-string to a string string str1b ( "Hello " ); cout << "The string str1b is: " << str1b << endl; const char *cstr1b = "Out There "; cout << "The C-string cstr1b is: " << cstr1b << endl; str1b.append ( cstr1b , 3 ); cout << "Appending the 1st part of the C-string cstr1b " << "to string str1 gives: " << str1b << "." << endl << endl; // The third member function // appending part of one string to another string str1c ( "Hello " ), str2c ( "Wide World " ); cout << "The string str2c is: " << str2c << endl; str1c.append ( str2c , 5 , 5 ); cout << "The appended string str1 is: " << str1c << "." << endl << endl; // The fourth member function // appending one string to another in two ways, // comparing append and operator [ ] string str1d ( "Hello " ), str2d ( "Wide " ), str3d ( "World " ); cout << "The string str2d is: " << str2d << endl; str1d.append ( str2d ); cout << "The appended string str1d is: " << str1d << "." << endl; str1d += str3d; cout << "The doubly appended strig str1 is: " << str1d << "." << endl << endl; // The fifth member function // appending characters to a string string str1e ( "Hello " ); str1e.append ( 4 , '!' ); cout << "The string str1 appended with exclamations is: " << str1e << endl << endl; // The sixth member function // appending a range of one string to another string str1f ( "Hello " ), str2f ( "Wide World " ); cout << "The string str2f is: " << str2f << endl; str1f.append ( str2f.begin ( ) + 5 , str2f.end ( ) - 1 ); cout << "The appended string str1 is: " << str1f << "." << endl << endl; }
輸出
3.c++ assign 將新的字元值指派給字串的內容
定義
basic_string<CharType, Traits, Allocator>& assign(const value_type* ptr);
basic_string<CharType, Traits, Allocator>& assign(const value_type* ptr, size_type count);
basic_string<CharType, Traits, Allocator>& assign(const basic_string<CharType, Traits, Allocator>& str, size_type off, size_type count);
basic_string<CharType, Traits, Allocator>& assign(const basic_string<CharType, Traits, Allocator>& str);
basic_string<CharType, Traits, Allocator>& assign(size_type count, value_type char_value);
template <class InIt>
basic_string<CharType, Traits, Allocator>& assign(InputIterator first, InputIterator last);
basic_string<CharType, Traits, Allocator>& assign(const_pointer first, const_pointer last);
basic_string<CharType, Traits, Allocator>& assign(const_iterator first, const_iterator last);
參數
ptr
要指派給目標字串之 C 字串的字元指標。
count
要從來源字串指派的字元數。
str
其字元要指派給目標字串的來源字串。
char_value
要指派的字元值。
first
輸入迭代器 const_pointer 或 const_iterator,為來源字串範圍中要指派給目標範圍的第一個字元定址。
last
輸入迭代器 const_pointer 或 const_iterator,為來源字串範圍中要指派給目標範圍的最後一個字元以外的字元定址。
off
即將開始指派新字元的位置。
傳回值
正由成員函式指派新字元之字串物件的參考。
備註
字串可以指派新的字元值。 新的值可以是字串和 C 字串,或是單一字元。 operator=
如果可由單一參數描述新的值,則可使用,否則, assign
具有多個參數的成員函式可以用來指定要將字串的哪個部分指派給目標字串。
範例
// basic_string_assign.cpp // compile with: /EHsc #include <string> #include <iostream> int main( ) { using namespace std; // The first member function assigning the // characters of a C-string to a string string str1a; const char *cstr1a = "Out There"; cout << "The C-string cstr1a is: " << cstr1a << "." << endl; str1a.assign ( cstr1a ); cout << "Assigning the C-string cstr1a to string str1 gives: " << str1a << "." << endl << endl; // The second member function assigning a specific // number of the of characters a C-string to a string string str1b; const char *cstr1b = "Out There"; cout << "The C-string cstr1b is: " << cstr1b << endl; str1b.assign ( cstr1b , 3 ); cout << "Assigning the 1st part of the C-string cstr1b " << "to string str1 gives: " << str1b << "." << endl << endl; // The third member function assigning a specific number // of the characters from one string to another string string str1c ( "Hello " ), str2c ( "Wide World " ); cout << "The string str2c is: " << str2c << endl; str1c.assign ( str2c , 5 , 5 ); cout << "The newly assigned string str1 is: " << str1c << "." << endl << endl; // The fourth member function assigning the characters // from one string to another string in two equivalent // ways, comparing the assign and operator = string str1d ( "Hello" ), str2d ( "Wide" ), str3d ( "World" ); cout << "The original string str1 is: " << str1d << "." << endl; cout << "The string str2d is: " << str2d << endl; str1d.assign ( str2d ); cout << "The string str1 newly assigned with string str2d is: " << str1d << "." << endl; cout << "The string str3d is: " << str3d << "." << endl; str1d = str3d; cout << "The string str1 reassigned with string str3d is: " << str1d << "." << endl << endl; // The fifth member function assigning a specific // number of characters of a certain value to a string string str1e ( "Hello " ); str1e.assign ( 4 , '!' ); cout << "The string str1 assigned with eclamations is: " << str1e << endl << endl; // The sixth member function assigning the value from // the range of one string to another string string str1f ( "Hello " ), str2f ( "Wide World " ); cout << "The string str2f is: " << str2f << endl; str1f.assign ( str2f.begin ( ) + 5 , str2f.end ( ) - 1 ); cout << "The string str1 assigned a range of string str2f is: " << str1f << "." << endl << endl; }
輸出
4.c++ at 使用字串中的指定索引,提供字元的參考
定義
const_reference at(size_type offset) const;
reference at(size_type offset);
參數
offset
要參考之元素的位置索引。
傳回值
位於參數索引所指定之位置的字串字元參考。
備註
字串的第一個元素的索引為零,且下列元素會以正整數連續編制索引,因此長度為 n 的字串會有 n 個第 n 個元素,並以數位 n-1 來編制索引。
成員 operator
[]比 at
提供字串元素之讀取和寫入存取權的成員函式更快。
此成員 operator[]
不會檢查當做參數傳遞的索引是否有效,但成員函式是否有效 at
,而且如果有效性不確定,則應該使用。 傳遞給成員函式的索引無效(索引小於零或大於或等於字串的大小)會擲回 at
out_of_range
類別例外狀況。 傳遞給 operator[]
的索引若無效會導致未定義的行為,但等於字串長度的索引是 const 字串的有效索引,而且當傳遞此索引時,運算子會傳回 Null 字元。
傳回的參考可能會因為字串重新分配或非字串的修改而失效 const
。
範例
// basic_string_at.cpp // compile with: /EHsc #include <string> #include <iostream> int main( ) { using namespace std; string str1 ( "Hello world" ), str2 ( "Goodbye world" ); const string cstr1 ( "Hello there" ), cstr2 ( "Goodbye now" ); cout << "The original string str1 is: " << str1 << endl; cout << "The original string str2 is: " << str2 << endl; // Element access to the non const strings basic_string <char>::reference refStr1 = str1 [6]; basic_string <char>::reference refStr2 = str2.at ( 3 ); cout << "The character with an index of 6 in string str1 is: " << refStr1 << "." << endl; cout << "The character with an index of 3 in string str2 is: " << refStr2 << "." << endl; // Element access to the const strings basic_string <char>::const_reference crefStr1 = cstr1 [ cstr1.length ( ) ]; basic_string <char>::const_reference crefStr2 = cstr2.at ( 8 ); if ( crefStr1 == '0' ) cout << "The null character is returned as a valid reference." << endl; else cout << "The null character is not returned." << endl; cout << "The character with index 8 in the const string cstr2 is: " << crefStr2 << "." << endl; }
輸出
5.c++ capacity 傳回可儲存在字串中且不增加字串的記憶體配置的最大元素數目
定義
size_type capacity() const;
傳回值
目前在記憶體中配置以保留字串的儲存空間大小。
備註
成員函式會傳回目前配置用來保存受控制序列的儲存體,此值至少會與相同 size
。
範例
// basic_string_capacity.cpp // compile with: /EHsc #include <string> #include <iostream> int main( ) { using namespace std; string str1 ("Hello world"); cout << "The original string str1 is: " << str1 << endl; // The size and length member functions differ in name only basic_string <char>::size_type sizeStr1, lenStr1; sizeStr1 = str1.size ( ); lenStr1 = str1.length ( ); basic_string <char>::size_type capStr1, max_sizeStr1; capStr1 = str1.capacity ( ); max_sizeStr1 = str1.max_size ( ); // Compare size, length, capacity & max_size of a string cout << "The current size of original string str1 is: " << sizeStr1 << "." << endl; cout << "The current length of original string str1 is: " << lenStr1 << "." << endl; cout << "The capacity of original string str1 is: " << capStr1 << "." << endl; cout << "The max_size of original string str1 is: " << max_sizeStr1 << "." << endl << endl; str1.erase ( 6, 5 ); cout << "The modified string str1 is: " << str1 << endl; sizeStr1 = str1.size ( ); lenStr1 = str1.length ( ); capStr1 = str1.capacity ( ); max_sizeStr1 = str1.max_size ( ); // Compare size, length, capacity & max_size of a string // after erasing part of the original string cout << "The current size of modified string str1 is: " << sizeStr1 << "." << endl; cout << "The current length of modified string str1 is: " << lenStr1 << "." << endl; cout << "The capacity of modified string str1 is: " << capStr1 << "." << endl; cout << "The max_size of modified string str1 is: " << max_sizeStr1 << "." << endl; }
輸出
6.c++ clear 清除字串的所有元素
定義
void clear();
備註
呼叫成員函式所在的字串將會是空的。
範例
// basic_string_clear.cpp // compile with: /EHsc #include <string> #include <iostream> int main( ) { using namespace std; string str1 ("Hello world"), str2; basic_string <char>::iterator str_Iter; cout << "The original string str1 is: "; for ( str_Iter = str1.begin( ); str_Iter != str1.end( ); str_Iter++ ) cout << *str_Iter; cout << endl; str1.clear ( ); cout << "The modified string str1 is: "; for ( str_Iter = str1.begin( ); str_Iter != str1.end( ); str_Iter++ ) cout << *str_Iter; cout << endl; //For an empty string, begin is equivalent to end if ( str1.begin ( ) == str1.end ( ) ) cout << "Nothing printed above because " << "the string str1 is empty." << endl; else cout << "The string str1 is not empty." << endl; }
輸出
7.c++ compare
使用指定的字串進行區分大小寫的比較,以判斷兩個字串是否相等,或其中一個字串是否小於另一個字串詞典編纂
定義
int compare( const basic_string<CharType, Traits, Allocator>& str) const;
int compare( size_type position_1, size_type number_1, const basic_string<CharType, Traits, Allocator>& str) const;
int compare( size_type position_1, size_type number_1, const basic_string<CharType, Traits, Allocator>& str, size_type offset, size_type count) const;
int compare( const value_type* ptr) const;
int compare( size_type position_1, size_type number_1, const value_type* ptr) const;
int compare( size_type position_1, size_type number_1, const value_type* ptr size_type number_2) const;
參數
str
要與運算元字串比較的字串。
position_1
比較開始處的運算元字串索引。
number_1
要比較之運算元字串的字元數上限。
number_2
要比較之參數字串的字元數上限。
offset
比較開始處的參數字串索引。
count
要比較之參數字串的字元數上限。
ptr
要與運算元字串比較的 C 字串。
傳回值
如果運算元字串小於參數字串,則為負值;如果兩個字串相等,則為零;如果運算元字串大於參數字串,則為正值。
備註
成員函式會 compare
根據所使用的參數和運算元字串的全部或部分進行比較。
比較會區分大小寫。
範例
// basic_string_compare.cpp // compile with: /EHsc #include <string> #include <iostream> int main( ) { using namespace std; // The first member function compares // an operand string to a parameter string int comp1; string s1o ( "CAB" ); string s1p ( "CAB" ); cout << "The operand string is: " << s1o << endl; cout << "The parameter string is: " << s1p << endl; comp1 = s1o.compare ( s1p ); if ( comp1 < 0 ) cout << "The operand string is less than " << "the parameter string." << endl; else if ( comp1 == 0 ) cout << "The operand string is equal to " << "the parameter string." << endl; else cout << "The operand string is greater than " << "the parameter string." << endl; cout << endl; // The second member function compares part of // an operand string to a parameter string int comp2a, comp2b; string s2o ( "AACAB" ); string s2p ( "CAB" ); cout << "The operand string is: " << s2o << endl; cout << "The parameter string is: " << s2p << endl; comp2a = s2o.compare ( 2 , 3 , s2p ); if ( comp2a < 0 ) cout << "The last three characters of " << "the operand stringn are less than " << "the parameter string." << endl; else if ( comp2a == 0 ) cout << "The last three characters of " << "the operand stringn are equal to " << "the parameter string." << endl; else cout << "The last three characters of " << "the operand stringn is greater than " << "the parameter string." << endl; comp2b = s2o.compare ( 0 , 3 , s2p ); if ( comp2b < 0 ) cout << "The first three characters of " << "the operand stringn are less than " << "the parameter string." << endl; else if ( comp2b == 0 ) cout << "The first three characters of " << "the operand stringn are equal to " << "the parameter string." << endl; else cout << "The first three characters of " << "the operand stringn is greater than " << "the parameter string." << endl; cout << endl; // The third member function compares part of // an operand string to part of a parameter string int comp3a; string s3o ( "AACAB" ); string s3p ( "DCABD" ); cout << "The operand string is: " << s3o << endl; cout << "The parameter string is: " << s3p << endl; comp3a = s3o.compare ( 2 , 3 , s3p , 1 , 3 ); if ( comp3a < 0 ) cout << "The three characters from position 2 of " << "the operand string are less thann " << "the 3 characters parameter string " << "from position 1." << endl; else if ( comp3a == 0 ) cout << "The three characters from position 2 of " << "the operand string are equal ton " << "the 3 characters parameter string " << "from position 1." << endl; else cout << "The three characters from position 2 of " << "the operand string is greater thann " << "the 3 characters parameter string " << "from position 1." << endl; cout << endl; // The fourth member function compares // an operand string to a parameter C-string int comp4a; string s4o ( "ABC" ); const char* cs4p = "DEF"; cout << "The operand string is: " << s4o << endl; cout << "The parameter C-string is: " << cs4p << endl; comp4a = s4o.compare ( cs4p ); if ( comp4a < 0 ) cout << "The operand string is less than " << "the parameter C-string." << endl; else if ( comp4a == 0 ) cout << "The operand string is equal to " << "the parameter C-string." << endl; else cout << "The operand string is greater than " << "the parameter C-string." << endl; cout << endl; // The fifth member function compares part of // an operand string to a parameter C-string int comp5a; string s5o ( "AACAB" ); const char* cs5p = "CAB"; cout << "The operand string is: " << s5o << endl; cout << "The parameter string is: " << cs5p << endl; comp5a = s5o.compare ( 2 , 3 , s2p ); if ( comp5a < 0 ) cout << "The last three characters of " << "the operand stringn are less than " << "the parameter C-string." << endl; else if ( comp5a == 0 ) cout << "The last three characters of " << "the operand stringn are equal to " << "the parameter C-string." << endl; else cout << "The last three characters of " << "the operand stringn is greater than " << "the parameter C-string." << endl; cout << endl; // The sixth member function compares part of // an operand string to part of an equal length of // a parameter C-string int comp6a; string s6o ( "AACAB" ); const char* cs6p = "ACAB"; cout << "The operand string is: " << s6o << endl; cout << "The parameter C-string is: " << cs6p << endl; comp6a = s6o.compare ( 1 , 3 , cs6p , 3 ); if ( comp6a < 0 ) cout << "The 3 characters from position 1 of " << "the operand string are less thann " << "the first 3 characters of the parameter C-string." << endl; else if ( comp6a == 0 ) cout << "The 3 characters from position 2 of " << "the operand string are equal ton " << "the first 3 characters of the parameter C-string." << endl; else cout << "The 3 characters from position 2 of " << "the operand string is greater thann " << "the first 3 characters of the parameter C-string." << endl; cout << endl; }
輸出
8.c++ copy
從來源字串中的索引位置,最多複製指定的字元數到目標字元陣列。
此方法有賴於呼叫者檢查傳遞的值是否正確,因此可能不安全。 請考慮 basic_string::_Copy_s
改為使用。
定義
size_type copy( value_type* ptr, size_type count, size_type offset = 0) const;
參數
ptr
要複製元素的目標字元陣列。
count
要從來源字串複製的字元數上限。
offset
來源字串中要建立複本的開始位置。
傳回值
已複製的字元數。
備註
Null 字元不會附加至複本的結尾。
範例
// basic_string_copy.cpp // compile with: /EHsc /W3 #include <string> #include <iostream> int main( ) { using namespace std; string str1 ( "Hello World" ); basic_string <char>::iterator str_Iter; char array1 [ 20 ] = { 0 }; char array2 [ 10 ] = { 0 }; basic_string <char>:: pointer array1Ptr = array1; basic_string <char>:: value_type *array2Ptr = array2; cout << "The original string str1 is: "; for ( str_Iter = str1.begin( ); str_Iter != str1.end( ); str_Iter++ ) cout << *str_Iter; cout << endl; basic_string <char>:: size_type nArray1; // Note: string::copy is potentially unsafe, consider // using string::_Copy_s instead. nArray1 = str1.copy ( array1Ptr , 12 ); // C4996 cout << "The number of copied characters in array1 is: " << nArray1 << endl; cout << "The copied characters array1 is: " << array1 << endl; basic_string <char>:: size_type nArray2; // Note: string::copy is potentially unsafe, consider // using string::_Copy_s instead. nArray2 = str1.copy ( array2Ptr , 5 , 6 ); // C4996 cout << "The number of copied characters in array2 is: " << nArray2 << endl; cout << "The copied characters array2 is: " << array2Ptr << endl; }
輸出
結論
這七個函數應該不是所有的C++字串類別的函數,只不過是大叔看了一下,先列出七個有印象常用的函數,後面有需要的話,再列出其他常用的函數。
C++字串類別是一個抽象的資料型態,它不是C++原本內建的資料型態,如 int或 char,C++字串類別與字串類別函數是定義於C++的新型標題檔中,而 C型態的字串標題檔(cstring)並沒有定義這些函數,所以使用這些函數以前,比須插入 C++新型的標題檔(string)。
這裡有你最常用的函數嗎?歡迎留言告訴我,謝謝。
※2022/04/02 最近這幾日在寫C#時使用indexof跟contains的頻率還滿高的,我猜C++的find跟substr c++的功能很類似,今天再來補充一個find函式
find 以正向方向搜尋字串中,第一個符合指定之字元序列的子字串。
定義
size_type find(value_type char_value, size_type offset = 0) const;
size_type find(const value_type* ptr, size_type offset = 0) const;
size_type find(const value_type* ptr, size_type offset, size_type count) const;
size_type find(const basic_string<CharType, Traits, Allocator>& str, size_type offset = 0) const;
參數
char_value
要搜尋之成員函式的字元值。
offset
開始搜尋位置的索引。
ptr
要搜尋之成員函式的 C 字串。
count
要搜尋之成員函式的 C 字串中,從第一個字元開始往前計數的字元數目。
str
要搜尋之成員函式的字串。
傳回值
在成功時,為搜尋的子字串的第一個字元的索引,否則為 npos
。
範例
// g++ std-find1.cpp -o a.out #include <iostream> #include <algorithm> using namespace std; int main() { int arr[] = {2, 3, 4, 5, 6}; int *p = std::find(arr, arr+4, 3); // find 3 if (p == arr+4) { cout << "not findn"; } else { cout << "found " << *p << "n"; } return 0; }
- 編譯器
- 設定C和C++ Code::Blocks編譯器的初學者教學指南:如果你苦惱的是編譯器的使用,可以看看設定C和C++ Code::Blocks編譯器的初學者教學指南。
- Code::Blocks 13.12 繁體中文化:如果想要使用code block 中文的朋友可以繼續閱讀Code::Blocks 13.12 繁體中文化,這裡不會有code block中文亂碼的問題。
- 設定Dev-C++ 5.11和MinGW-w64, Windows上免費的C跟C++編譯器
- C跟C++的Apple XCode
- g++簡介
- 使用Microsoft Visual C++ 2010 Express編譯GTK+
- Eclipse+CDT+MinGW 安裝測試
- 編譯器gcc
- Code::Blocks 20.03的安裝設定及繁體中文化
4 則留言