.注重:你應(yīng)該去了解一下"string-n”函數(shù),雖然它們使用起來(lái)有些困難,但用它們編寫(xiě)的程序兼容性更好,錯(cuò)誤更少。 假如你愿意的話,可以用函數(shù)strcpy()和strcat()重新編寫(xiě)例12.5a中的程序,并用很長(zhǎng)的足以溢出緩沖區(qū)的參數(shù)運(yùn)行它。會(huì)出現(xiàn)什么現(xiàn)象呢?計(jì)算機(jī)會(huì)掛起嗎?你會(huì)得到"GeneralPRotection Exception”或內(nèi)存信息轉(zhuǎn)儲(chǔ)這樣的消息嗎?請(qǐng)參見(jiàn)7.24中的討論。 例12.5a使用"string—n”函數(shù)的一個(gè)例子 # include <stdio. h> # include <string. h> /* Normally, a constant like MAXBUF would be very large, to help ensure that the buffer doesn't overflow. Here, it's very small, to show how the "string-n" functions prevent it from ever overflowing. */ # define MAXBUF 16 int main (int argc, char* * argv) { char buf[MAXBUF]; int i; buf[MAXBUF - 1] = '/0'; strncpy(buf, argv[0], MAXBUF-1); for (i = 1; i<argc; ++i) { strncat(buf, " " , MAXBUF -1 - strlen (buf) ) ; strncat(buf, argv[i], MAXBUF -1 - strlen (buf ) ) ; } puts (buf ); return 0; }
注重:許多字符串函數(shù)都至少有兩個(gè)參數(shù),在描述它們時(shí),與其稱之為“第一個(gè)參數(shù)”和“第二個(gè)參數(shù)”,還不如稱之為“左參數(shù)”和“右參數(shù)”。 函數(shù)strcpy()和strncpy()用來(lái)把字符串從一個(gè)數(shù)組拷貝到另一個(gè)數(shù)組,即把右參數(shù)的值拷貝到左參數(shù)中,這與賦值語(yǔ)句的順序是一樣的。 函數(shù)strcat()和strncat()用來(lái)把一個(gè)字符串連接到另一個(gè)字符串的末尾。例如,假如數(shù)組a1的內(nèi)容為“dog”,數(shù)組a2的內(nèi)容為“wood”,那么在調(diào)用strcat(al,a2)后,a1將變?yōu)椤癲ogwood”。 函數(shù)strcmp()和strncmp()用來(lái)比較兩個(gè)字符串。當(dāng)左參數(shù)小于、等于或大于右參數(shù)時(shí),它們都分別返回一個(gè)小于、等于或大于零的值。常見(jiàn)的比較兩個(gè)字符串是否相等的寫(xiě)法有以下兩種: if (strcmp(sl, s2)) { / * si !=s2 * / } 和 if (! strcmp(s1, s2)) { /* s1 ==s2 * / } 上述代碼可能并不易讀,但它們是完全有效并且相當(dāng)常見(jiàn)的c代碼,你應(yīng)該記住它們。假如在比較字符串時(shí)還需要考慮當(dāng)前局部環(huán)境(locale,見(jiàn)12.8),則要使用strcoll()函數(shù)。 有一些函數(shù)用來(lái)在字符串中進(jìn)行檢索(在任何情況下,都是在左參數(shù)或第一個(gè)參數(shù)中進(jìn)行檢索)。函數(shù)strchr()和strrchr()分別用來(lái)查找某個(gè)字符在一個(gè)字符串中第一次和最后一次出現(xiàn)的位置(假如函數(shù)strchr()和strrchr()有帶“n”字母的版本,那么函數(shù)memchr()和memrchr()是最接近這種版本的函數(shù))。函數(shù)strspn()、strcspn()(“c”表示"complement")和strpbrk()用來(lái)查找包含指定字符或被指定字符隔開(kāi)的子字符串: n = strspn("Iowa" , "AEIOUaeiou"); / * n = 2( "Iowa" starts with 2 vowels * / n=strcspn("Hello world" ,"/t" ) ; / * n = 5; white space after 5 characters * / p = strbrk("Hellb world" ,"/t" ) ; / * p points to blank * /
函數(shù)strstr()用來(lái)在一個(gè)字符串中查找另一個(gè)字符串: p = strstr("Hello world", "or"); / * p points to the second "or" * /
函數(shù)strtok()按照第二個(gè)參數(shù)中指定的字符把一個(gè)字符串分解為若干部分。函數(shù)strtok()具有“破壞性”,它會(huì)在原字符串中插入NUL字符(假如原字符串還要做其它的改變,應(yīng)該拷貝原字符串,并將這份拷貝傳遞給函數(shù)strtok())。函數(shù)strtok()是不能“重新進(jìn)入”的,你不能在一個(gè)信號(hào)處理函數(shù)中調(diào)用strtok()函數(shù),因?yàn)樵谙乱淮握{(diào)用strtok()函數(shù)時(shí)它總是會(huì)“記住”上一次被調(diào)用時(shí)的某些參數(shù)。strtok()函數(shù)是一個(gè)古怪的函數(shù),但它在分解以逗號(hào)或空白符分界的數(shù)據(jù)時(shí)是非常有用的。例12.5b給出了一個(gè)程序,該程序用strtok()函數(shù)把一個(gè)句子中的單詞分解出來(lái): 例12.5b一個(gè)使用strtok()的例子 # include <stdio. h> # include <string. h> static char buf[] = "Now is the time for all good men . . . " ; int main() { char * p; p = strtok(buf, " ") ; while (p ) { printf("%s/n" ,p); p = strtok(NULL, " "); } return 0; }