字元串:是以空字元\0為結尾的char數組 在程式中定義字元串的方法 1.字元串常量(字元串文字):是指位於一對雙引號中的任何字元,雙引號里的字元加上編譯器自動提供的結束標誌\0字元,作為一個字元串背儲存在記憶體里。它常常用作printf和puts的參數。 2.字元串數組:定義一個字元串數組時,必須讓 ...
字元串:是以空字元\0為結尾的char數組
在程式中定義字元串的方法
1.字元串常量(字元串文字):是指位於一對雙引號中的任何字元,雙引號里的字元加上編譯器自動提供的結束標誌\0字元,作為一個字元串背儲存在記憶體里。它常常用作printf和puts的參數。
2.字元串數組:定義一個字元串數組時,必須讓編譯器知道它需要多大的空間。一種方法是指定以一個足夠大的數組來容納字元串,而通常,讓編譯器決定數組大小更為方便。(在進行初始化聲明時如果省略了數組大小,則其大小由編譯器決定)。
常見的定義字元串的方法
①#define MSG "this is a string"
②char msg[50] = "this is a string"; char msg[] = "this is a string";
const char msg[50] = "this is a string"; const char msg[] = "this is a string";
③char *msg = "this is a string"; const char *msg = "this is a string";
④char *msg[3] = {"this is the first string","this is the second string","this is the third string"};
const char *msg[3] = {"this is the first string","this is the second string","this is the third string"};
字元串常量屬於靜態存儲類,即使多次使用了字元串常量,該字元串在程式的整個運行過程中只存儲一份。整個引號中的內容作為指向該字元串存儲位置的指針。這一點與把數組名作為指向數組存儲位置的指針類似,即把字元串看作指針。
例如:對於字元串“We are the champion”,
若在printf中用%s輸出,則輸出引號中所有內容,即“We are the champion”。
若以%p輸出,則輸出的使字元串中第一個字元的地址,此處即'W'的地址。
若以%c輸出*”We are the champion“,則輸出字元串“We are the champion”中的第一個字元,此處即W。因為“We are the champion”是地址,等於該字元串第一個字元(W)的地址,故*“We are the champion”的值即為該地址中的值,即W。
比較char *msg和char msg[]
在數組形式中,msg是個地址常量。您不能更改msg,因為這意味著更改數組存儲的位置(地址)。
可以實用msg+1來表示數組裡的下一個元素(==msg[1]),但是不允許實用++msg或msg++,因為增量運算符只能用在變數名前,而此處msg使個地址常量。
在指針形式中,msg指向字元串的第一個字元,它的值使可以變的。因此可以對他使用增量運算符。例如,++msg將指向第二個字元。
總之,數組初始化是從靜態存儲區把要給字元串複製給數組,而指針初始化只是賦值字元串的地址(==字元串第一個字元的地址)。
比較char *msg[SIZE]和char (*msg)[SIZE]
表達式中[]的優先順序高於*,因此圓括弧的有無會造成很大不同。
char *msg[SIZE]表示msg是一個包含SIZE個元素的數組,而數組中的每個元素都是一個指向char值的指針。該種形式可以用來聲明一個字元串數組。
msg數組中存放的是字元串的地址,而實際上字元串存在於程式用來存放常量的那部分記憶體中。可以把msg[0]看作指向第一個字元串開始的指針,*msg[0]表示第一個字元串的第一個字元,由於數組符號和指針之間的關係,它等價於msg[0][0],儘管msg並沒有被定義成二維數組
char (*msg)[SIZE]表示msg首先是一個指針,它指向的是一個包含SIZE個char值的數組,該種形式可以用來聲明指向二維數組的指針變數。
字元串的輸入
如果想把字元串讀到程式中,必須首先預留存儲字元串的空間,然後使用輸入函數來獲取這個字元串。
創建存儲空間的方法
1.利用char數組,需要分配足夠大的存儲區來存放希望讀入的字元串,需要在聲明中明確指出數組大小。例如,char msg[50];
2.利用C庫里分配存儲空間的函數。例如,char *ptd; ptd = (char *) malloc (SIZE * sizeof(char));這段代碼請求SIZE個char類型值的空間,並且把ptd指向該空間所在位置。
輸入函數
gets()函數,它讀取換行符之前(不包括換行符)所有字元,在這些字元後添加一個空字元\0,然後把這個字元串交給調用它的程式。它使用一個地址作為參數,可以使數組名,也可以是初始化過的(已分配記憶體的)指針。如果遇到文件結尾,gets就返回空指針NULL。
註意,gets不檢查目標數組是否能夠容納輸入!常見形式為:char name[50]; gets(name);
fgets()函數,它需要您指定最大輸入字元數和讀哪個文件(鍵盤為stdin)。如果這個參數值為n,fgets就會讀取最多n-1個字元或者讀完一個換行符為止,由這二者中最先滿足的那個來結束輸入。它讀取到換行符,不會像gets那樣丟棄,而是存儲到字元串里。常見形式:char name[50]; fgets(name,50,stdin);
scanf()函數,更基於獲取單詞而不是字元串。它以%s格式讀取,以遇到的第一個非空白字元開始,讀到(但不包括)下一個空白字元。如果指定了欄位寬度如%10s,則會讀取10個字元或者直到遇到第一個空白字元,由二者中最先滿足的那個中只輸入。常見形式:char name[50]; scanf("%s",name);
輸出函數
puts()函數,其參數為字元串的地址,它會在顯示字元串時自動在其後添加一個換行符。
常見形式:puts(name); puts("this is a string!");
fputs()函數,它是puts面向文件版本,需要第二個參數來說明要寫的文件,且fputs不為輸出自動添加換行符。
常見格式:fputs(name,stdout);
printf()函數,它沒有puts那麼方便,但是它可以格式化多種數據類型,因而更通用。它使得在一行上輸出多個字元串變得更為簡單。
常見形式:printf("Well,%s %s\n",name,MSG);