1. 程式人生 > >C語言入門(十六)之字串

C語言入門(十六)之字串

字串的基本概念

如何定義字串變數, 由於字串是同一種類型的資料組成,  並且是有序的。
而陣列就是用於儲存很多同一種類型的有序資料, 所以可以使用陣列來儲存字串。

注意: 字串變數和普通的字元陣列有一定的區別。

C語言規定, 字串必須以\0結尾(作為字串的結束符號), 所以字串變數的元素個數比字元陣列的元素個數多一個 \0

char str1[] = "lnj";
char str2[] = {'l', 'n', 'j', '\0'};
printf("str size = %lu\n", sizeof(str1));
printf("charValues size = %lu\n", sizeof(str2));

輸出長度都為4

str size = 4
charValues size = 4

如何輸出字串變數, %s。

str 陣列的名稱, 陣列的名稱就是陣列的地址。

%s的原理, 從傳入的"地址"開始逐個取出, 直到遇到"\0"位置。

如果定義一個如下字元陣列。

char str2[] = {'x', '\0' ,'m', 'g'}; // 字元陣列
printf("str = %s\n", str2);

會輸出

str = x

需要明白的一點就是字串以\0結尾, 沒有\0就不是字串;
只要是用雙引號括起來的都是字串;
字串的本質就是陣列;

char str6[] = "lnj";
str6[1] = 'y';
    
printf("%s", str6);

字串常用方法

1、可以使用puts函式來輸出

優點: 可以自動換行
缺點: 不可以自定義格式, 只能原樣輸出

char str[] = "lnj";
puts(str);
printf("-------\n");

2、利用scanf接收字串的注意點

scanf接收字串, 會以空格 , tab, 回車作為結束符號, 也就是說利用scanf接收字串時, 字串中不能出現空格, tab, 回車

3、利用gets接收字串

// warning: this program uses gets(), which is unsafe.
// 如果使用gets接收字串, 系統會提示我們正在使用一個不安全的方法接收字元
// 優點: 如果利用gets接收字串 , 可以在字串中輸入空格, tab
printf("請輸入一個字串\n");
char buf2[10]; // lnj c
gets(buf2);
printf("buf = %s\n", buf2);

4、如何計算字串的長度strlen

strlen的原理: 從傳入的地址開始逐個取出字串, 每取出一個就讓計數器+1. 直到遇到\0為止

char str[] = "lnj cool";
size_t size =  strlen(str); // 計算出來的結果不包括\0
printf("length = %lu\n", size);//輸出 length = 8

模擬strlen函式

int length = sizeof(str) / sizeof(str[0]);
int size = myStrlen2(str, length);

printf("length = %lu\n", size);

int myStrlen2(char str[], int length)
{
    // 1.定義變數記錄取出了多少個字元
    int count = 0;
    // 2.遍歷字元陣列
    for (int i = 0; i < length; i++) {
        if (str[i] != '\0') {
            count++;
        }
    }
    return count;
}

5、字串拼接函式

// 原理 : 首先遍歷第一個字串,直到遇到\0為止, 然後取出第二個字串中的字元, 從\0的位置開始新增, 新增完畢之後再在最後新增一個\0
     
    char str1[7] = "lnj"; // l n j c o o l \0
    char str2[10] = " cool";
    printf("拼接前: %s\n", str1);
    // dest : 目標 src : 源
    // 將src中的資料拼接到dest後面
    // 注意: 要想使用字串拼接函式, 那麼dest必須是一個數組, 並且陣列的長度必須大於拼接之後的長度 \
    如果dest陣列的長度, 不能完全存放dest+src+\0, 那麼就會報錯
//    strcat(str1, str2);
    
    // char * 相當於dest  const char * 相當於src size_t 需要拼接的個數
    // 為了避免拼接之後超出str1的儲存範圍, 那麼可以動態計算str2中需要拷貝幾個到str1後面不會超出
//                  str1能夠存放的元素個數            -   str1已經存放的個數  - \0
//計算str1中所剩容量
    size_t length = sizeof(str1) / sizeof(str1[0]) - strlen(str1) - 1;
    printf("length = %lu\n", length);
    strncat(str1, str2, length);
    printf("拼接後: %s\n", str1);

6、字串拷貝函式strcpy

    char str1[4] = "lnj";
    char str2[] = "cool";
    printf("拷貝前 : str1 = %s\n", str1);
    // char * 目標, const char * 源
    // strcpy函式會將源的資料拷貝到目標中, 並且會覆蓋掉目標中原有的資料
    // 目標的容積必須能夠存放拷貝的資料, 如果容積不夠會報錯
//    strcpy(str1, str2);
    
    // char * 目標, const char * 源 size_t 需要拷貝幾個
    // 注意: 拷貝操作是逐個替換, 拷貝了幾個就替換幾個
    //              str1能夠存放元素的個數         - 1是給\0留出位置
    int length = sizeof(str1) / sizeof(str1[0]) - 1;
    strncpy(str1, str2, length);
    printf("拷貝後 : str1 = %s\n", str1);

7、字串比較函式strcmp

    char str1[] = "aac"; // a a
    char str2[] = "abc"; // a b

    // strcmp它會對傳入的字串進行比較, 比較完畢之後會返回一個整型的值給我們
    // 如果該值等於0,那麼證明兩個字串相等
    // 如果該值小於0, 那麼證明str1小於str2
    // 如果該值大於0, 那麼證明str1大於str2
    // strcmp的原理: 取出字串中的每一個字元進行逐個比較, 如果發現不相等就不會繼續往下比較
    int res = strcmp(str1, str2);
    printf("res = %i\n", res);

字串練習

// 編寫一個函式char_contains(char str[],char key), 如果字串str中包含字元key則返回數值1,否則返回數值0
// 給你一個字串和一個key, 要求從字串中找出key, 如果找到就返回1沒有找到就返回0

char str[] = "xiaomage";
char key = 'z';

int res = char_contains2(str, key);
printf("res = %i\n", res);

int char_contains2(char str[],char key)
{
     // 1.定義一個變數記錄當前的索引
     //    int index = 0;
     // 2.遍歷陣列, 取出當前的字元判斷是否不等於key, 並且當前出去的字元不是\0

    int index = -1;
    while (str[++index] != key && str[index] != '\0');
    return str[index] != '\0' ? 1 : 0;
}

字串陣列

#include <stdio.h>

int main(int argc, const char * argv[]) {
    
    char name1[] = "lnj";
    char name2[] = "lmj";
    char name3[] = "xb";
    char name4[] = "lk";
    
    // 如果想儲存一堆字串那麼可以使用字串陣列
    // 說白了字串陣列就是二維陣列
    char names[5][20] =
    {
        "lnj",
        "lmj",
        "xb",
        "lk",
        "xj"
    }
    
    char names2[2][20] =
    {
        {'l', 'n', 'j', '\0'},
        {'l', 'm', 'j', '\0'}
    }
    
    return 0;
}