由於在C++項目中,經常遇到處理字元方面的問題,故藉此機會整理一下,讓自己對於char , string 等有進一步的瞭解。 基本概念 由單引號括起來的一個字元成為char型字面值。雙引號括起來的零個或多個字元則構成字元串型字面值。 字元串字面值得類型=>由常量字元構成的數組,併在結尾處添加一個空字 ...
由於在C++項目中,經常遇到處理字元方面的問題,故藉此機會整理一下,讓自己對於char , string 等有進一步的瞭解。
- 基本概念
由單引號括起來的一個字元成為char型字面值。雙引號括起來的零個或多個字元則構成字元串型字面值。
'a' // 字元字面值 "Hello World!"//字元串字面值
字元串字面值得類型=>由常量字元構成的數組,併在結尾處添加一個空字元('\0');因此字元串字面值的實際長度比它的內容多1。
'A'//單獨的字元A
"A"//包含兩個字元,一個字母A,一個空字元。
- C標準庫String函數
strlen(p) | 返回p的長度,空字元不計算在內,傳入此類函數的指針必須紙箱以空字元作為結束的數組。 |
strcmp(p1,p2) |
比較p1和p2的相等性。如果p1 == p2,返回0;如果p1>p2,返回一個正值;如果p1<p2,返回一個負值。 傳入此類函數的指針必須紙箱以空字元作為結束的數組。 |
strcat(p1,p2) | 將p2附加到p1之後,返回p1;傳入此類函數的指針必須紙箱以空字元作為結束的數組。 |
strcpy(p1,p2) | 將p2拷貝給p1,返回p1;傳入此類函數的指針必須紙箱以空字元作為結束的數組。 |
char ca [] = {'C', '+', '+'}; //不以空字元結束 cout << strlen(ca)<<endl; //錯誤,ca沒有以空字元結束
當使用數組的時候,其實真正用的是指向數組首元素的指針。
混用string對象和C風格字元串
- 允許使用以空字元結束的字元數組來初始化string對象或為string對象賦值;
- 在string對象的加法運算中允許使用以空字元結束的字元數組作為其中一個運算對象(不能兩個運算對象都是);在string對象的複合賦值運算中允許使用以空字元結束的字元數組作為右側的運算對象。
上述返過來就不行,如下:
不能用string對象直接初始化指向字元的指針。為此,string提供了c_str的成員函數,來實現此效果。
string s("Hello World"); //可以,s內容是 Hello World char * str = s; //錯誤 const char *str = s.c_str(); //正確 ,註意是 const char *
c_str函數返回結果是一個指針,指向一個以空字元結束的字元數組,而這個數組所存的數據恰好與那個string對象的一樣。結果指針的類型是const char *,從而確保我們不會改變字元數組的內容。
註意:c_str()返回的數組無法保證一直有效,如果後續的操作改變了s的值,就可能讓之前返回的數組失效。
如果執行完c_str()函數後程式想一直都能使用其返回的數組,最好將該數組重新拷貝一份。
- 標準庫類型 String
標準庫string表示可變長的字元序列,首先要包含string頭文件,且string定義在命名空間std中。
string s1 ;//預設初始化,s1是一個空串 string s2(s1); // s2 是 s1 的副本 string s2 = s1; // 等價於s2(s1),s2 是s1的副本 string s3("value") ;//s3是字面值value的副本,不過沒有後面的那個空字元 string s3 = "value";//等價於s3("value"),s3 是字面值"value"的副本。 string s4(n,'c'); // 把s4初始化為由連續n個字元c組成的串。
有關標準類型String對象上的操作有s.size() s.empty() s1+s2 s1 = s2 s[n] s1==s2 < <= > >= !=
- 數組方面
字元數組的特殊性:它有一種額外的初始化形式,可以用字元串字面值對此類數組初始化。
char a1[] = {'C', '+', '+'};//列表初始化,沒有空字元 char a2[] = {'C', '+', '+','\0'}; // 列表初始化,含有顯式的空字元 char a3[] = "C++" ;//會自動添加表示字元串結束的空字元 const char a4[6] = "Daniel"; //錯誤,沒有空間可存放空字元
string 類型數組:
string a4[3] = {"hi","bye"};//等價於a4[] = {"hi","bye",""};
在C語言中,可以使用以下方式:
char *str ="hello world"; //但是這種方式在IOS C++11 運行下不行。
C語言有兩種表示字元串的方法,一種是字元數組,另一種是字元串常量,它們在記憶體中的存儲位置不同,使得字元數組可以讀取和修改,而字元串常量只能讀取不能修改。
#include <stdio.h> int main(){ char *str = "Hello World!"; str = "I love C!"; //正確 str[3] = 'P'; //錯誤 return 0; }
在編程過程中如果只涉及到對字元串的讀取,那麼字元數組和字元串常量都能夠滿足要求;如果有寫入(修改)操作,那麼只能使用字元數組,不能使用字元串常量。
這兩種方式(字元數組和字元串指針)它們最根本的區別是在記憶體中的存儲區域不一樣,字元數組存儲在全局數據區或棧區,第二種形式的字元串存儲在常量區。全局數據區和棧區的字元串(也包括其他數據)有讀取和寫入的許可權,而常量區的字元串(也包括其他數據)只有讀取許可權,沒有寫入許可權。
還有一點需要註意,就是當用到sizeof時:
char *str1 = "hello wrold"; char str2[] = "hello world"; cout<<sizeof(str1); //8 機子是64位 cout << sizeof(str2); //12