字串比較、搜尋


若要進行字串的比較,可以使用 strcmpstrncmp

int strcmp( const char *lhs, const char *rhs );
int strncmp( const char *lhs, const char *rhs, size_t count );

strcmp(str1, str2) 會比較字串 str1str2 的大小,若相同就傳回 0,str1 大於 str2 則傳回大於 0 的值,小於則傳回小於 0 的值,比較的標準是依字典順序,例如若 str1 大於 str2,表示 str1 在字典中的順序是在 str2 之後。

strncmp 是比較兩個字串中指定長度內的字元是否相同,一個字串比較範例如下所示:

#include <stdio.h>
#include <string.h>
#define LEN 80

int main(void) {
    char passwd[] = "123456";
    char buf[LEN];

    printf("請輸入密碼:");
    fgets(buf, LEN, stdin);

    if(strncmp(passwd, buf, 6) == 0) {
        puts("密碼正確");
    }
    else {
        puts("密碼錯誤");
    }

    return 0;
}

執行結果:

請輸入密碼:123456
密碼正確

C 標準函式庫也提供了搜尋字串的相關函式,先來看到 strstr 函式:

char *strstr( const char* str, const char* substr );

第一個參數是被搜尋字串,第二個參數是想要搜尋的子字串,如果沒找到子字串則傳回 NULL,如果搜尋到第一個符合的子字串,則傳回符合位置的指標,若想要得知子字串是在哪一個索引位置,則可以利用該指標減去字串(字元陣列)開頭的指標,得到的位移量即為符合的索引位置,一個範例如下所示:

#include <stdio.h>
#include <string.h>
#define LEN 80

int main(void) {
    char source[LEN];
    char search[LEN];

    printf("輸入字串:");
    fgets(source, LEN, stdin);

    printf("搜尋子字串:");
    fgets(search, LEN, stdin);

    // 去除最後的換行字元
    search[strlen(search) - 1] = '\0';

    char *loc = strstr(source, search);

    if(loc == NULL) {
        printf("找不到符合的子字串\n");
    }
    else {
        printf("在索引位置 %lu 處找到子字串\n", loc - source);
    }

    return 0;
}

執行結果:

輸入字串:How do you do?
搜尋子字串:you
在索引位置 7 處找到子字串

相對於 strstr 函式找出符合的子字串,strspn 函式則用來比較兩個字串,找出兩個字串中開始不匹配的地方:

size_t strspn( const char *dest, const char *src );

strspn 會傳回兩個字串開始不匹配的第一個字元索引位置,否則傳回 0,一個使用範例如下:

#include <stdio.h>
#include <string.h>
#define LEN 80

int main(void) {
    char str1[LEN];
    char str2[LEN];

    printf("輸入字串:");
    fgets(str1, LEN, stdin);

    printf("搜尋子字串:");
    fgets(str2, LEN, stdin);
    // 去除最後的換行字元
    str2[strlen(str2) - 1] = '\0';

    size_t loc = strspn(str1, str2);

    if(loc == strlen(str1)) {
        printf("完全匹配\n");
    }
    else {
        printf("從索引位置 %lu 處開始不匹配\n", loc);
    }

    return 0;
}

執行結果:

輸入字串:How do you do?
搜尋子字串:How do joe do?
從索引位置 7 處開始不匹配

以上都是直接搜尋字串中的子字串,以下介紹的是搜尋字串中的字元。

strchr 函式找出字串中的指定字元第一次出現,若找到則傳回該字元的指標,否則傳回 NULL,可以用找到的指標位置減去字串(字元陣列)開頭位址,如此就可以得到其於字串中的索引位置,而 strrchr 則是與 strchr 類似,只不過它是反向搜尋:

char *strchr( const char *str, int ch );
char *strrchr( const char *str, int ch );

strcspn 函式則是找出一個字串中與另一個字串任何字元第一次匹配的索引位置,若無則傳回字串長度:

size_t strcspn( const char *dest, const char *src );

直接寫個範例示範 strcspn 函式之使用:

#include <stdio.h>
#include <string.h>
#define LEN 80

int main(void) {
    char str1[LEN];
    char str2[LEN];

    printf("輸入字串:");
    fgets(str1, LEN, stdin);

    printf("搜尋子字串:");
    fgets(str2, LEN, stdin);
    // 去除最後的換行字元
    str2[strlen(str2) - 1] = '\0';

    size_t loc = strcspn(str1, str2);

    if(loc == strlen(str1)) {
        printf("沒有任何字元匹配\n");
    }
    else {
        printf("索引位置 %lu 處匹配到字元\n", loc);
    }

    return 0;
}

執行結果:

輸入字串:How do you do?
搜尋子字串:wo
索引位置 1 處匹配到字元

strpbrk 函式則與 strcspn 類似,只不過完全不匹配的話,則傳回 NULL

char* strpbrk( const char* dest, const char* breakset );