字串函數之間的轉換,首先要先瞭解C++字串的組成,C++提供了兩種字串的表示:C 風格的字串和標準 C++引入的 string 類類型。
1. C 風格字串
C 風格的字串起源於 C 語言 並在 C++中繼續得到支援。字串被儲存在一個字元數組中 一般通過一個 char*類型的指標來操縱它 。
標準 C 庫為操縱 C 風格的字串提供了一組函數,例如:
int strlen( const char* ); // 返回字串的長度
int strcmp( const char*, const char* ); // 比較兩個字串是否相等
char* strcpy(char*, const char* ); // 把第二個字串拷貝到第一個字串中
標準 C 庫作為標準的 C++的一部分被包含在其中。為使用這些函數,我們必須包含相關的 C 標頭檔#include <cstring>
1.1 不調用庫函數,實現C風格字串的常用基本函數
#include<iostream>#include<cstring>#include<cassert>using namespace std;/*返回字串長度*/int MyStrlen(const char * ch){assert(ch!=NULL);int i=0,count=0;const char *t=ch;//用一個臨時指標去遍曆,防止改變原來指標指向。while(t[i]!='\0'){count++;i++;}return count;}/*把第二個字串拷貝到第一個字串中,返回第一個字串的首部指標。*/char* MyStrcpy(char *des,const char *src){assert((des!=NULL)&&(src!=NULL));int i=0;char *add=des;//用add記錄des的首部。while(src[i]!='\0'){des[i]=src[i];i++;}des[i]='\0';return add;}/*比較兩個字串是否相等。相等則返回0,前一個字串比後一個小則返回-1,否則返回1。*/int MyStrcmp(const char *ch1,const char *ch2){assert((ch1!=NULL)&&(ch2!=NULL));int i=0;const char *str1=ch1;//定義兩個臨時指標。const char *str2=ch2;while((str1[i]!='\0')||(str2[i]!='\0')){if(str1[i]<str2[i]){return -1;}else if(str1[i]>str2[i]){return 1;}else{i++;}}return 0;}int main(){char ch[]="cavely";char ch2[]="julia";cout<<MyStrlen(ch)<<endl;//6cout<<MyStrcmp(ch,ch2)<<endl;//-1/*下面這兩句不能寫成:char ch3[100];ch3=MyStrcpy(ch,ch2);//數組名是一個地址【常量】。不能被賦值*/char *ch3;ch3=MyStrcpy(ch,ch2);cout<<ch3<<endl;//juliareturn 0;}
2.string 類類型
要使用 string 類型 必須先包含相關的標頭檔#include <string>
string str("hello"); //①定義一個帶初值的字串
string str2; // ②定義Null 字元串
string str3( str ); //③用一個 string 對象來初始化另一個 string 對象
2.1 對字串類的基本操作:
(1)str的長度由 size()操作返回(不包含終止Null 字元),例如str.size()的值為5。
(2)使用 empty()操作判斷字串是否為空白,例如:str2.empty()。如果字串中不含有字元,則 empty()返回布爾常量 true ,否則返回 false。
(3)還可以直接使用賦值操作符 = 拷貝字串,例如:st2 = st3; // 把 st3 拷貝到 st2 中
(4)可以使用加操作符 + 或看起來有點怪異的複合賦值操作符 += 將兩個或多個字串串連起來。例如,給出兩個字串
string s1( "hello, " );
string s2( "world\n" );
我們可以按如下方式將兩個字串串連起來形成第三個字串
string s3 = s1 + s2;
如果希望直接將 s2 附加在 s1 後面 那麼可使用 += 操作符
s1 += s2;
(5)string 類型支援通過下標操作符訪問單個字元,例如,在下面的程式碼片段中,字串中的所有句號被底線代替。
string str( "fa.disney.com" );int size = str.size();for ( int ix = 0; ix < size; ++ix )if ( str[ ix ] == '.' ) str[ ix ] = '_';
上面程式碼片段的實現可用如下語句替代:
replace( str.begin(), str.end(), '.', '_' );
replace()是泛型演算法中的一個,begin()和 end()操作返回指向 string 開始和結束處的迭代器(iterator) 。迭代器是指標的類抽象 ,由標準庫提供。replace()掃描 begin()和 end()之間的字元。每個等於句號的字元,都被替換成底線。
2.2 C 風格的字串與 string 對象的轉換
string 類型能夠自動將 C 風格的字串轉換成 string 對象。例如,這使我們可以將一個 C 風格的字串賦給一個 string 對象。
string s1;
const char *pc = "a character array";
s1 = pc; //OK
但是,反向的轉換不能自動執行。對隱式地將 string 對象轉換成 C 風格的字串 string類型沒有提供支援。例如下面,試圖用 s1 初始化 str 就會在編譯時間刻失敗。
char *str = s1; // 編譯時間刻類型錯誤
為實現這種轉換,必須顯式地調用名為 c_str()的操作。名字 c_str()代表了 string 類型與 C 風格字串兩種標記法之間的關係。字面意思是,給我一個 C 風格的字串表示——即 指向字元數組起始處的字元指標。為了防止字元數組被程式直接處理, c_str()返回了一個指向常量數組的指標 const char*
所以,正確的初始化應該是:const char *str = s1.c_str(); // OK