學習C++ -> 字符串
一、字符串的概念
用雙引號括起來的一串字符稱為字符串, 例如 "abc"、"Hello, world!"。C++延續了C語言中的做法, 將字符串使用字符型(char)一維數組來存放, 在存放字符串時, 編譯器會在字符串結束的位置自動添加"\0", "\0"是 ASCII 碼值為0的轉義符, 它是字符串的結束標志, 對於這種存放方式, 稱它為字符數組更為合適。
在字符串中, 有效字符的個數稱為字符串的長度, 例如字符串"abc"的長度為3, 但它所占的字節數為4字節, 因為編譯器會在結束時自動添加一個 "\0", 也就是說, 定義長度為n的字符型一維數組只能存放下n-1個字符, 否則將無法存放結束標識"\0", 在某些情況下將導致字符串無法正常使用, 嚴重時可導致一些未知的錯誤。
二、字符串的實現
字符型一維數組的定義同普通數組一樣, 只要把數組的數組類型改為 char 型即可, 例如:
char a[10] ; char b[20] ;
在定義完一維字符數組時也可以對其進行初始化, 初始化分為兩種方式:
1>.逐個字符進行初始化, 例如:
char a[6] = { 'H', 'e', 'l', 'l', 'o', '\0' } ;
此時a[0]中存放'H'字符, a[1]中存放'e'字符..., 這里的大括號不能省略, 同時初始化的字符個數也不能超過數組定義的長度, 不過在初始化時字符數組的元素個數聲明可以省略, 這樣編譯器會自動計算好后面初始化中所需的數組長度, 如:
char a[] = { 'H', 'e', 'l', 'l', 'o', '\0' } ;
像下面對字符數組的初始化都是錯誤的:
char a[6] = { 'H', 'e', 'l', 'l', 'o', ',', 'w', 'o', 'r', 'l', 'd', '\0' } ; //錯誤! 初始值的長度超過了數組定義的長度 char a[6] = 'H', 'e', 'l', 'l', 'o', '\0' ; //錯誤! 沒有使用大括號
2>. 使用字符串常量初始化方式, 例如:
char a[6] = {"Hello"} ;
由於編譯器會自動在字符串末尾添加'\0'字符, 所以字符數組a的各元素存放的內容依次為: 'H', 'e', 'l', 'l', 'o', '\0'。
在上述初始化形式中, 大括號可以省略, 並且在初始化時數組元素的長度聲明也可以省略, 編譯器會根據初始化值中的字符個數(包括'\0')自動計算數組所需的元素個數, 以下聲明都是正確的:
char a[6] = "Hello" ; char a[] = "Hello" ;
三、字符串的使用
舉例一: 定義一個字符串並輸出
#include<iostream> using namespace std ; int main() { char a[] = "Hello" ; //定義並初始化一個字符串· cout<< a ; //輸出該一維字符數組中的字符串 return 0 ; }
此外, 字符數組還可以進行逐個輸出或者逐個替換操作。
舉例二: 輸出其中某一個字符, 並將字符數組中的某個字符替換成其他字符。
#include<iostream> using namespace std ; int main() { char a[] = "Hello" ; //定義並初始化一個字符串· cout<< a[2] <<endl ; //輸出a[2]中保存的字符 a[0] = 'W' ; //將a[0]中的'H'替換成'W' cout<<a ; //全部輸出 return 0 ; }
四、字符串的輸入
1>. 使用cin進行輸入, 舉例:
#include<iostream> using namespace std ; int main() { char a[50] ; cin>>a ; //輸入字符串a cout<<a ; //輸入后進行輸出 return 0 ; }
使用cin進行輸入主要使用在字符串輸入過程沒有空白符(空格、tab)的情況下, 當存輸入過程中按下空格鍵或tab鍵時cin就會默認輸入結束, 當再按下回車進行時, 也只存空白符前面的內容, 例如:
hello world <-這里輸入的是帶有空格的 hello world hello <-可以看到, 輸出時只剩下了空格前面的hello Process returned 0 (0x0) execution time : 7.578 s Press any key to continue.
注意: 如果連續輸入的字符數超過了49個, 則可能會引起內存錯誤!
2>. cin.get() 函數
如果想連空格一起輸入到字符數組中可以使用 cin.get() 函數, 舉例:
#include<iostream> using namespace std ; int main() { char a[50] ; cin.get(a, 50) ; //輸入字符串a cout<<a ; //輸入后進行輸出 return 0 ; }
在 cin.get(a, 50) ; 這行, a是要輸入字符串的數組名, 后面的50為最長允許獲取多少字符, 當值為50時表示只獲取輸入的前49個字符, 當值為10時表示只獲取輸入的前10個字符。
3>. cin.getline() 函數
cin.getling() 函數也可起到輸入一行並包含空格的作用, 使用舉例:
#include<iostream> using namespace std ; int main() { char a[50] ; cin.getline(a, 50) ; //輸入字符串a cout<<a ; //輸入后進行輸出 return 0 ; }
4>. cin.get() 與 cin.getline() 的不同之處
雖說這兩個函數都能夠用來輸入帶有空格的字符串, 但還是有不同之處的, 兩個函數都用於讀入一行輸入, 直至遇到換行符, 但是 getline() 函數會將換行符從輸入隊列中提取出來並拋棄掉, 而 get() 函數不會將換行符從輸入隊列中提取並拋棄掉, 這乍一看區別不大, 實際上在有連續幾行的輸入時這將會對輸入結果產生很大的影響。舉例:
#include<iostream> using namespace std ; int main() { char a[50], b[50] ; //定義兩個字符數組 cout<<"請輸入字符串一:" ; cin.get(a, 50) ; //輸入字符串a cout<<"請輸入字符串二:" ; cin.get(b, 50) ; //輸入字符串b cout<<a ; //輸入后進行輸出 cout<<b ; return 0 ; }
運行后的輸入以及輸出:
請輸入字符串一:hello my name 請輸入字符串二:hello my name Process returned 0 (0x0) execution time : 7.031 s Press any key to continue.
如果我們自己編譯運行后可以發現, 當我們輸入完畢第一行字符串, 還沒來得及輸入第二行時程序就已經運行結束了, 這就是因為 get() 函數會將換行符留在輸入隊列所致, 當輸入完第一行時我們按下回車, get 函數獲取輸入的內容, 並把換行符留在了輸入隊列, 當執行到 cin.get(b, 50) ; 時正好他得到的第一個字符不是用戶的輸入, 而是遺留在上一次輸入的換行符, 這樣它就誤認為用戶輸入以及結束了而自動結束輸入。
由於 get() 函數不會拋棄輸入隊列中的換行符, 因此在使用 get() 函數進行輸入時可以使用一個較為完善的輸入方式:
cin.get(數組名, 允許長度).get() ;
這樣當第一個 get() 獲取到用戶輸入並存放到字符數組后, 第二個 get() 會負責把換行符提取出來, 相當於拋棄掉, 這樣在下一行使用函數進行輸入時就不會再出現還沒有輸入程序就已經默認為輸入已經結束的情況。
五、字符串處理函數
數組不能整體的進行加減乘除比較等操作, 例如以下操作都是錯誤的:
char a[50] = "Hello" ; char b[50] = "world" ; if(a == b) //錯誤! a += b ; //錯誤! a = a + "abc" ; //錯誤!
可以看出, 在字符串操作上比較的不方便, 為了方便編程的進行, 在C++的標准庫里給我們提供好了一些能夠對字符串方便操作的函數, 我們只需要調用函數就行了, 要使用這些函數, 需要包含頭文件 cstring
#include<cstring>
一些常用的字符串處理函數如下:
| 操作 |
函數原型 | 說明 |
| 取得字符串長度 |
size_t strlen(數組名) | 不包括結束標志'\0' |
| 將源字符數組中的字符串復制到目標數組 | char *strcpy(目標數組, 源數組名) | 目標數組的大小應不小於源字符串 |
| 字符串大小比較 | int strcmp(字符串1, 字符串2) | 相等返回0, 字符串1大於字符串2返回正數, 否則返回一個負數 |
| 將兩個字符串連接起來 | char *strcat(字符串1, 字符串2) | 將字符串2連接到字符串1后面, 字符串1必須有足夠的剩余位置容納字符串2 |
| 將字符串中的小寫字符全部轉成大寫 | char *strupr(數組名) | |
| 將字符串中的大寫字符全部轉成小寫 | char *strlwr(數組名) |
需要說明的是關於字符串的大小比較, 字符串的大小比較不是比較其長度, 而是比較從左向右依次比較每個字符的ASCII的值的大小, 如果第一個字符串的第一個字符的ASCII值大於第二個就說明字符串1大於字符串2, 依次類推。
字符串處理函數使用舉例: 測量字符串的長度並將該字符串全部轉成大寫后輸出:
#include<iostream> #include<cstring> using namespace std ; int main() { char a[50] = "Hello, I am C++ !" ; int n ; //用來保存字符串的長度值 n = strlen(a) ; //測量字符串長度 cout<<n<<endl ; //輸出長度 strupr(a) ; //將字符串全部轉為大寫 cout<<a ; //輸出轉換后的字符串 return 0 ; }
--------------------
wid, 2012.12.06
上一篇: 學習C++ -> 一維數組
