1. 程式人生 > >字串操作函式

字串操作函式

1)字串操作
strcpy(p, p1) 複製字串
strncpy(p, p1, n) 複製指定長度字串
strcat(p, p1) 附加字串
strncat(p, p1, n) 附加指定長度字串
strlen(p) 取字串長度
strcmp(p, p1) 比較字串
strcasecmp忽略大小寫比較字串
strncmp(p, p1, n) 比較指定長度字串
strchr(p, c) 在字串中查詢指定字元
strrchr(p, c) 在字串中反向查詢
strstr(p, p1) 查詢字串
strpbrk(p, p1) 以目標字串的所有字元作為集合,在當前字串查詢該集合的任一元素
strspn(p, p1) 以目標字串的所有字元作為集合,在當前字串查詢不屬於該集合的任一元素的偏移
strcspn(p, p1) 以目標字串的所有字元作為集合,在當前字串查詢屬於該集合的任一元素的偏移 
* 具有指定長度的字串處理函式在已處理的字串之後填補零結尾符 

2)字串到數值型別的轉換
strtod(p, ppend) 從字串 p 中轉換 double 型別數值,並將後續的字串指標儲存到 ppend 指向的 char* 型別儲存。
strtol(p, ppend, base) 從字串 p 中轉換 long 型別整型數值,base 顯式設定轉換的整型進位制,設定為 0 以根據特定格式判斷所用進位制,0x, 0X 字首以解釋為十六進位制格式整型,0    字首以解釋為八進位制格式整型
atoi(p) 字串轉換到 int 整型
atof(p) 字串轉換到 double 符點數
atol(p) 字串轉換到 long 整型 

3)字元檢查
isalpha() 檢查是否為字母字元
isupper() 檢查是否為大寫字母字元
islower() 檢查是否為小寫字母字元
isdigit() 檢查是否為數字
isxdigit() 檢查是否為十六進位制數字表示的有效字元
isspace() 檢查是否為空格型別字元
iscntrl() 檢查是否為控制字元
ispunct() 檢查是否為標點符號
isalnum() 檢查是否為字母和數字
isprint() 檢查是否是可列印字元
isgraph() 檢查是否是圖形字元,等效於 isalnum() | ispunct() 

4)函式原型
原型:strcpy(char destination[], const char source[]);
功能:將字串source拷貝到字串destination中
例程: 
 #include <iostream.h>
#include <string.h>
void main(void)
{
  char str1[10] = { "TsinghuaOK"};
  char str2[10] = { "Computer"};
  cout <<strcpy(str1,str2)<<endl;
}

執行結果是:Computer
第二個字串將覆蓋掉第一個字串的所有內容!
注意:在定義陣列時,字元陣列1的字串長度必須大於或等於字串2的字串長度。不能用賦值語句將一個字串常量或字元陣列直接賦給一個字元陣列。所有字串處理函式都包含在標頭檔案string.h中。


strncpy(char destination[], const char source[], int numchars);

strncpy:將字串source中前numchars個字元拷貝到字串destination中。
strncpy函式應用舉例
原型:strncpy(char destination[], const char source[], int numchars);
功能:將字串source中前numchars個字元拷貝到字串destination中
例程: 

#include <iostream.h>
#include <string.h>
void main(void)
{
  char str1[10] = { "Tsinghua "};
  char str2[10] = { "Computer"};
  cout <<strncpy(str1,str2,3)<<endl;
}

執行結果:Comnghua
注意:字串source中前numchars個字元將覆蓋掉字串destination中前numchars個字元!

原型:strcat(char target[], const char source[]);
功能:將字串source接到字串target的後面
例程:
#include <iostream.h>
#include <string.h>
void main(void)
{
  char str1[] = { "Tsinghua "};
  char str2[] = { "Computer"};
  cout <<strcpy(str1,str2)<<endl;
}

執行結果:Tsinghua Computer

注意:在定義字元陣列1的長度時應該考慮字元陣列2的長度,因為連線後新字串的長度為兩個字串長度之和。進行字串連線後,字串1的結尾符將自動被去掉,在結尾串末尾保留新字串後面一個結尾符。 

原型:strncat(char target[], const char source[], int numchars);
功能:將字串source的前numchars個字元接到字串target的後面
例程:

#include <iostream.h>
#include <string.h>
void main(void)
{
  char str1[] = { "Tsinghua "};
  char str2[] = { "Computer"};
  cout <<strncat(str1,str2,3)<<endl;
}

執行結果:Tsinghua Com


原型:int strcmp(const char firststring[], const char secondstring);
功能:比較兩個字串firststring和secondstring
例程: 

#include <iostream.h>
#include <string.h>
void main(void)
{
  char buf1[] = "aaa";
  char buf2[] = "bbb";
  char buf3[] = "ccc";
  int ptr; 
  ptr = strcmp(buf2,buf1); 
  if(ptr > 0)
   cout <<"Buffer 2 is greater than buffer 1"<<endl;
  else 
   cout <<"Buffer 2 is less than buffer 1"<<endl;
  ptr = strcmp(buf2,buf3); 
  if(ptr > 0)
   cout <<"Buffer 2 is greater than buffer 3"<<endl;
  else 
   cout <<"Buffer 2 is less than buffer 3"<<endl;
}

執行結果是:Buffer 2 is less than buffer 1 
                  Buffer 2 is greater than buffer 3


原型:strlen( const char string[] );
功能:統計字串string中字元的個數
例程: 

#include <iostream.h>
#include <string.h>
void main(void)
{
  char str[100]; 
  cout <<"請輸入一個字串:";
  cin >>str;
  cout <<"The length of the string is :"<<strlen(str)<<"個"<<endl;
}

執行結果The length of the string is x (x為你輸入的字元總數字)

注意:strlen函式的功能是計算字串的實際長度,不包括'\0'在內。另外,strlen函式也可以直接測試字串常量的長度,如:strlen("Welcome")。

 
void *memset(void *dest, int c, size_t count); 
將dest前面count個字元置為字元c.  返回dest的值. 

void *memmove(void *dest, const void *src, size_t count); 
從src複製count位元組的字元到dest. 如果src和dest出現重疊, 函式會自動處理.  返回dest的值. 

void *memcpy(void *dest, const void *src, size_t count); 
從src複製count位元組的字元到dest. 與memmove功能一樣, 只是不能處理src和dest出現重疊.  返回dest的值. 

void *memchr(const void *buf, int c, size_t count); 
在buf前面count位元組中查詢首次出現字元c的位置. 找到了字元c或者已經搜尋了count個位元組, 查詢即停止. 操作成功則返回buf中首次出現c的位置指標, 否則返回NULL. 

void *_memccpy(void *dest, const void *src, int c, size_t count); 
從src複製0個或多個位元組的字元到dest. 當字元c被複制或者count個字元被複制時, 複製停止. 

如果字元c被複制, 函式返回這個字元後面緊挨一個字元位置的指標. 否則返回NULL. 

int memcmp(const void *buf1, const void *buf2, size_t count); 
比較buf1和buf2前面count個位元組大小. 
返回值< 0, 表示buf1小於buf2; 
返回值為0, 表示buf1等於buf2; 
返回值> 0, 表示buf1大於buf2. 

int memicmp(const void *buf1, const void *buf2, size_t count); 

比較buf1和buf2前面count個位元組. 與memcmp不同的是, 它不區分大小寫. 

返回值同上. 

char *strrev(char *string); 
將字串string中的字元順序顛倒過來. NULL結束符位置不變.  返回調整後的字串的指標. 

char *_strupr(char *string); 
將string中所有小寫字母替換成相應的大寫字母, 其它字元保持不變.  返回調整後的字串的指標. 

char *_strlwr(char *string); 
將string中所有大寫字母替換成相應的小寫字母, 其它字元保持不變.  返回調整後的字串的指標. 

char *strchr(const char *string, int c); 
查詢字  串string中首次出現的位置, NULL結束符也包含在查詢中.  返回一個指標, 指向字元c在字串string中首次出現的位置, 如果沒有找到, 則返回NULL. 

char *strrchr(const char *string, int c); 
查詢字元c在字串string中最後一次出現的位置, 也就是對string進行反序搜尋, 包含NULL結束符. 
返回一個指標, 指向字元c在字串string中最後一次出現的位置, 如果沒有找到, 則返回NULL. 

char *strstr(const char *string, const char *strSearch); 
在字串string中查詢strSearch子串.  返回子串strSearch在string中首次出現位置的指標. 如果沒有找到子串strSearch, 則返回NULL. 如果子串strSearch為空串, 函式返回string值. 

char *strdup(const char *strSource); 
函式執行中會自己呼叫malloc函式為複製strSource字串分配儲存空間, 然後再將strSource複製到分配到的空間中. 注意要及時釋放這個分配的空間. 
返回一個指標, 指向為複製字串分配的空間; 如果分配空間失敗, 則返回NULL值. 

char *strcat(char *strDestination, const char *strSource); 
將源串strSource新增到目標串strDestination後面, 並在得到的新串後面加上NULL結束符. 源串strSource的字元會覆蓋目標串strDestination後面的結束符NULL. 在字串的複製或新增過程中沒有溢位檢查, 所以要保證目標串空間足夠大. 不能處理源串與目標串重疊的情況.  函式返回strDestination值. 

char *strncat(char *strDestination, const char *strSource, size_t count); 
將源串strSource開始的count個字元新增到目標串strDest後. 源串strSource的字元會覆蓋目標串strDestination後面的結束符NULL. 如果count大於源串長度, 則會用源串的長度值替換count值. 得到的新串後面會自動加上NULL結束符. 與strcat函式一樣, 本函式不能處理源串與目標串重疊的情況. 函式返回strDestination值. 

char *strcpy(char *strDestination, const char *strSource); 
複製源串strSource到目標串strDestination所指定的位置, 包含NULL結束符. 不能處理源串與目標串重疊的情況.函式返回strDestination值. 

char *strncpy(char *strDestination, const char *strSource, size_t count); 
將源串strSource開始的count個字元複製到目標串strDestination所指定的位置. 如果count值小於或等於strSource串的長度, 不會自動新增NULL結束符目標串中, 而count大於strSource串的長度時, 則將strSource用NULL結束符填充補齊count個字元, 複製到目標串中. 不能處理源串與目標串重疊的情況.函式返回strDestination值. 

char *strset(char *string, int c); 
將string串的所有字元設定為字元c, 遇到NULL結束符停止. 函式返回內容調整後的string指標. 

char *strnset(char *string, int c, size_t count); 
將string串開始count個字元設定為字元c, 如果count值大於string串的長度, 將用string的長度替換count值. 函式返回內容調整後的string指標. 

size_t strspn(const char *string, const char *strCharSet); 
查詢任何一個不包含在strCharSet串中的字元 (字串結束符NULL除外) 在string串中首次出現的位置序號.  返回一個整數值, 指定在string中全部由characters中的字元組成的子串的長度. 如果string以一個不包含在strCharSet中的字元開頭, 函式將返回0值. 

size_t strcspn(const char *string, const char *strCharSet); 
查詢strCharSet串中任何一個字元在string串中首次出現的位置序號, 包含字串結束符NULL. 
返回一個整數值, 指定在string中全部由非characters中的字元組成的子串的長度. 如果string以一個包含在strCharSet中的字元開頭, 函式將返回0值. 

char *strspnp(const char *string, const char *strCharSet); 
查詢任何一個不包含在strCharSet串中的字元 (字串結束符NULL除外) 在string串中首次出現的位置指標. 返回一個指標, 指向非strCharSet中的字元在string中首次出現的位置. 

char *strpbrk(const char *string, const char *strCharSet); 
查詢strCharSet串中任何一個字元在string串中首次出現的位置, 不包含字串結束符NULL. 
返回一個指標, 指向strCharSet中任一字元在string中首次出現的位置. 如果兩個字串引數不含相同字元, 則返回NULL值. 

int strcmp(const char *string1, const char *string2); 
比較字串string1和string2大小. 
返回值< 0, 表示string1小於string2; 
返回值為0, 表示string1等於string2; 
返回值> 0, 表示string1大於string2. 

int stricmp(const char *string1, const char *string2); 
比較字串string1和string2大小,和strcmp不同, 比較的是它們的小寫字母版本.返回值與strcmp相同. 

int strcmpi(const char *string1, const char *string2); 
等價於stricmp函式, 只是提供一個向後相容的版本. 

int strncmp(const char *string1, const char *string2, size_t count); 
比較字串string1和string2大小,只比較前面count個字元. 比較過程中, 任何一個字串的長度小於count, 則count將被較短的字串的長度取代. 此時如果兩串前面的字元都相等, 則較短的串要小. 
返回值< 0, 表示string1的子串小於string2的子串; 
返回值為0, 表示string1的子串等於string2的子串; 
返回值> 0, 表示string1的子串大於string2的子串. 

int strnicmp(const char *string1, const char *string2, size_t count); 
比較字串string1和string2大小,只比較前面count個字元. 與strncmp不同的是, 比較的是它們的小寫字母版本.  返回值與strncmp相同. 

char *strtok(char *strToken, const char *strDelimit); 
在strToken 串中查詢下一個標記, strDelimit字符集則指定了在當前查詢呼叫中可能遇到的分界符. 返回一個指標, 指向在strToken中找到的下一個標記. 如果找不到標記, 就返回NULL值. 每次呼叫都會修改strToken內容, 用NULL字元替換遇到的每個分界符.

c++概念字串操作 

一、char_traits 字元特徵類
1)意義:包裝特定串元素的通用行為介面,以便容器實現時依據特徵資訊而執行特定行為
2)定義了通用型別名 

typedef _Elem char_type;
typedef int int_type;
typedef streampos pos_type;
typedef streamoff off_type;
typedef mbstate_t state_type; 

其中 int_type 表示字元元素轉換到特定編碼時的整型表示,pos_type, off_type 分別作為字串索引和字串元素偏移的型別,類似容器迭中的指標,迭代型別和指標,迭代器的偏移型別。最後的 state_type 用於儲存流狀態,如出錯,格式控制等等。 

3)定義了字元 / 字串操作的包裝介面,以便通用演算法的呼叫 

assign(a, b) 定義將 b 字元賦值給 a 字元的過程,實現 a.operator = 的行為
eq(a, b) 定義 a 字元和 b 字元的相等關係,實現 a.operator == 的行為
lt(a, b) 定義 a 小於 b 的關係,實現 a.operator < 的行為
compare(a_ptr, b_ptr, cnt) 定義兩組字串的比較,返回 int 型別,實現類似 memcmp 的行為
length(ptr) 定義取字串長度,實現類似 strlen 的行為
copy(a_ptr, b_ptr, cnt) 定義兩組字串的複製,實現類似 memcpy 的行為
move(a_ptr, b_ptr, cnt) 定義兩組字串的不重疊複製,實現類似 memmove 的行為
assign(ptr, cnt, ch) 定義了填充字串的過程,實現類似 memset 的行為
to_int_type(ch) 定義了 char_type 到 int_type 整型的轉換過程
to_char_type(n) 定義了 int_type 到 char_type 字元型的轉換過程
eq_int_type(a, b) 定義兩個和當前 char_type 型別對應的 int_type 的相等關係
eof() 定義字串結尾符,使用整型表示
not_eof(n) 定義非字串結尾符,若輸入結尾符,則返回 1,其他輸入返回原值,即總是不返回 eof() 

4)int_type 型別應是當前字元型別的整型編碼 

二、std::string 並不是序列容器,沒有 front() 和 back() 介面用於取出前端和尾端的元素,使用 std::string::operator [] 並傳遞 streampos 型別取得特定元素,如 std::string::size() - 1 作為索引取得最後一個字元 


三、basic_string 支援的初始化
1)預設初始化
2)分配器
3)複製構造
4)區域性複製 [_Roff, _Roff + _Count)
5)區域性複製 + 分配器
6)C 字串 [_Ptr, <null>)
7)C 字串 + _Count [_Ptr, _Ptr + _Count)
8)C 字串 + 分配器
9)C 字串 + _Count + 分配器 [_Ptr, _Ptr + _Count)

10)_Count * _Ch
11)_Count * _Ch + 分配器
12)迭代器 [_ItF, _ItL)
13)迭代器 + 分配器 

字元到串不能初始化,但支援 operator = 賦值和 operator += 累加賦值運算。 

四、字串的區間有效性
對串的索引訪問在超過字串的有效區間時,因為串的在實現上對內建的字元緩衝區執行下標訪問,所以不會導致異常,但是將得到不可預知的結果,通常是不可用的。
將其他字串作為右值輸入時,對該串取出計數大於串大小時按串大小計算。
std::basic_string::size_type 的實際型別為 size_t,在 Visual C++ 7.1 中實現為 unsigned,std::basic_string::npos 被靜態設定為 

(basic_string<_Elem, _Traits, _Alloc>::size_type)(-1); 

在查詢子字串等操作時,函式返回 npos 的值表示非法索引。 


五、比較字串
允許的比較物件
1)compare(s2) 其他同類型字串
2)compare(p) C 風格字串
3)compare(off, cnt, s2) [off, off + cnt) 同 s2 執行比較
4)compare(off, cnt, s2, off2, cnt2) [off, off + cnt) 同 s2 [off2, cnt2) 執行比較
5)compare(off, cnt, p) [off, off + cnt) 同 [p , <null>) 執行比較
6)compare(off, cnt, p, cnt2) [off, off + cnt) 同 [p, p + cnt2) 執行比較 

返回 -1, 0, 1 作為小於、等於和大於的比較結果。 

 六、附加資料
1)使用 operator += 接受其他字串,C 風格字串和字元
2)使用 push_back() 在尾部附加字元,並使得通過字串構造的 back_iterator 可以訪問
3)append() 附加
        1、append(s) 追加字串
        2、append(s, off, cnt) 追加字串 s [off, off + cnt)
        3、append(p) 追加字串 [p, <null>)
        4、append(p, cnt) 追加字串 [p, p + cnt)
        5、append(n, c) 填充 n * c
        6、append(InF, InL) 追加輸入流 [InF, InL) 

4)insert() 插入
        1、insert(off, s2) 插入字串
        2、insert(off, s2, off2, cnt2) 插入字串 s [off2, off2 + cnt2)
        3、insert(off, p) 插入字串 [p, <null>)
        4、insert(off, p, cnt) 插入字串 [p, p + cnt)

        5、insert(off, n, c) 插入 n * c
        6、insert(iter) 元素預設值填充
        7、insert(iter, c) 插入特定元素
        8、insert(iter, n, c) 插入 n*c
        9、insert(iter, InF, InL) 插入 [InF, InL) 

5)operator +(a, b)
字串關聯運算子過載中支援 operator + 的形式
        1、s + s
        2、s + p
        3、s + c
        4、p + s
        5、c + s 

七、查詢、替換和清除
1)find() 查詢
        1、find(c, off) 在 s [off, npos) 中查詢 c
        2、find(p, off, n) 在 s [off, npos) 中查詢 [p, p + n)
        3、find(p, off) 在 s [off, npos) 中查詢 [p, <null>)
        4、find(s2, off) 在 s [off, npos) 中查詢 s2 

2)find() 的變種
        1、rfind() 具有 find() 的輸入形式,反序查詢
        2、find_first_of() 具有 find() 的輸入形式,返回第一個匹配的索引
        3、find_last_of() 具有 find() 的輸入形式,返回倒數第一個匹配的索引
        4、find_first_not_of() 具有 find() 的輸入形式,返回第一個不匹配的索引
        5、find_last_not_of() 具有 find() 的輸入形式,返回倒數第一個不匹配的索引 

3)replace() 替換
        1、replace(off, cnt, s2) 將 s [off, off + cnt) 替換成 s2
        2、replace(off, cnt, s2, off2, cnt2) 將 s [off, off + cnt) 替換成 s2 [off2, off2 + cnt2)
        3、replace(off, cnt, p) 將 s [off, off + cnt) 替換成 [p, <null>)
        4、replace(off, cnt, p, cnt2) 將 s [off, off + cnt) 替換成 [p, p + cnt2)

        5、replace(off, cnt, n, c) 將 s [off, off + cnt) 替換成 c * n 

使用迭代器的情況:
        6、replace(InF, InL, s2) 將 [InF, InL) 替換成 s2
        7、replace(InF, InL, p) 將 [InF, InL) 替換成 [p, <null>)
        8、replace(InF, InL, p, cnt) 將 [InF, InL) 替換成 [p, p + cnt)
        9、replace(InF, InL, n, c) 將 [InF, InL) 替換成 n * c
        10、replace(InF, InL, InF2, InL2) 將 [InF, InL) 替換成 [InF2, InL2) 

4)erase() 刪除
        1、erase(off, cnt) 從字串 s 中刪除 s [off, off + cnt)
        2、erase(iter) 從字串 s 中刪除 *iter
        3、erase(ItF, ItL) 從字串 s 中刪除 [ItF, ItL) 

八、取出字串
1)取得 C 風格字串
c_str() 返回常量型別的 C 風格字串指標,copy(ptr, cnt, off = 0) 則將指定大小的字串複製到特定指標。data() 在 Visual C++ 7.1 中僅僅呼叫了 c_str() 實現。 
2)取得子字串
substr(off, cnt) 取得 s [off, off + cnt) 的副本。 
3)複製子字串
copy(p, off, cnt) 將 s [off, off + cnt) 複製到 p。 


九、字串的緩衝區管理
字串具有類似 std::vector 的緩衝區管理介面。 
size() 取得有效元素長度
max_size() 取得當前記憶體分配器能分配的有效空間
reserve() 為緩衝區預留空間
capacity() 取得緩衝區的容量
resize() 重設串的長度,可以為其指定初始化值 

  十、定義輸入迭代器的尾端
向 istream_iterator 傳遞輸入流物件以建立輸入迭代器,輸入迭代器持有輸入流物件的指標,預設建立和讀取流失敗的情況下該指標被設定為 0。並且在實現輸入迭代器間的 operator == 相等運算時,進行持有的流物件指標的相等比較,這樣,預設建立的輸入迭代器將被用於匹配輸入流的結束。 

* 當輸入流讀取失敗,使用者執行 if, while 條件判斷時,實際上先將判斷值轉換成 void* 型別,或者根據 operator ! 運算子的返回結果,對輸入流過載 operator void* 和 operator ! 運算子,可以定義輸入流在布林表示式中的行為,使得當流讀取失敗的情況下,輸入迭代器可以通過布林表示式來確認,而不是顯式訪問 fail() 成員函式.