個人主頁(找往期文章包括但不限于本期文章中不懂的知識點):我要學編程(?_?)-CSDN博客
目錄
strncpy函數的使用
函數原型:
strncpy的使用
strncat函數的使用
函數原型:?
strncat的使用?
strncmp函數的使用
函數原型:
strncmp的使用?
strstr的使用與模擬實現?
函數原型:
strstr的使用?
strstr的模擬實現?
strtok函數的使用?
函數原型:
strtok的使用
?編輯
strerror函數的使用?
函數原型:
strerror的使用?
字符分類函數
字符轉換函數?
strncpy函數的使用
函數原型:
//這里多了一個限制符:num,注意時size_t類型
char * strncpy ( char * destination, const char * source, size_t num );
? 拷貝num個字符從源字符串到目標空間。
? 如果源字符串的長度小于num,則拷貝完源字符串之后,在目標的后邊追加'\0',直到一共有num個。?
strncpy的使用
#include <stdio.h>
#include <string.h>
int main()
{char arr1[10] = { 0 };char arr2[10] = "xxxxxxxxxx";//為了更好地觀察‘補0’char arr3[] = "abc";strncpy(arr1, arr3, 2);strncpy(arr2, arr3, 5);printf("%s\n", arr1);printf("%s\n", arr2);return 0;
}
如果想要觀察就需要調試。
如果一旦目標空間不足,也會導致和strcpy一樣的結局。
strncat函數的使用
函數原型:?
//這里多了一個限制符:num,注意時size_t類型
char * strncat ( char * destination, const char * source, size_t num );
? 將源字符串的前num個字符追加到目標空間的末尾,再追加?個'\0'字符。
? 如果源字符串的長度小于num的時候,只會將源字符串中到'\0'的內容追加到目標空間的末尾。?
strncat的使用?
#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "hello ";char arr2[20] = "hello ";char arr3[] = "world";strncat(arr1, arr3, 3);strncat(arr2, arr3, 6);printf("%s\n", arr1);printf("%s\n", arr2);return 0;
}
strncmp函數的使用
函數原型:
//這里多了一個限制符:num,注意時size_t類型
int strncmp ( const char * str1, const char * str2, size_t num );
比較str1和str2的前num個字符,如果比較第一個字符相等就繼續往后比較,最多比較num個字符,如果提前發現不一樣,就提前結束,大的字符所在的字符串大于另外一個。如果num個字符都相等,就是相等返回0。?
strncmp的使用?
#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abcq";//比較到第四個字符時,d < q ,即返回一個小于0的數,第五個字符就不需要比較了int ret1 = strncmp(arr1, arr2, 5);//前三個字符都是相等的,所以就返回0int ret2 = strncmp(arr1, arr2, 3);printf("%d\n", ret1);printf("%d\n", ret2);return 0;
}
strstr的使用與模擬實現?
函數原型:
//字符串查找:在str1中查找str2(在源字符串中查找子字符串)
//查找成功是str2一定要連續在str1中
//例如:abcd中查找abc——>成功
// abcd中查找abd——>失敗
const char * strstr ( const char * str1, const char * str2 );char * strstr ( char * str1, const char * str2 );
查找成功,函數返回的是字符串str2在字符串str1中第一次出現的位置;查找失敗就會返回一個空指針(NULL)。
字符串的比較匹配不包含'\0'字符,以'\0'作為結束標志。也就是說當遇到'\0'字符時,我們的查找也就結束了,不需要再繼續進行查找了。?
strstr的使用?
#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "bcd";char arr3[] = "cdf";//如果arr2在arr1中找得到的話,就會返回arr2在arr1中的起始地址char* ret1 = strstr(arr1, arr2);//如果arr2在arr1中找不得到的話,就會返回一個空指針NULLchar* ret2 = strstr(arr1, arr3);printf("%s\n", ret1);printf("%s\n", ret2);return 0;
}
strstr的模擬實現?
思路分析:
我們寫的代碼肯定要符合那個多次匹配的情況。
#include <stdio.h>
#include <assert.h>
char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);//用一些變量來記錄我們要比較的指針const char* s1 = str1;const char* s2 = str2;const char* p = str1;while (*p)//因為s1在和s2比較的時候,會發生變化,不適合用*s1來{s1 = p;s2 = str2;while (*s1 != '\0' && *s1 == *s2 && *s2 != '\0'){s1++;s2++;}if (*s2 == '\0')//也就說明str2這個字符串已經找到了{return (char*)p;//避免警告,p被const修飾了}p++;//與上面的循環變量要一致}//跳出while循環也就意味著*p=='\0',即沒找到return NULL;
}int main()
{char arr1[] = "abbbcdef";char arr2[] = "bbc";char* ret = my_strstr(arr1, arr2);printf("%s\n", ret);return 0;
}
strtok函數的使用?
函數原型:
//字符串的分割
char * strtok ( char * str, const char * delimiters );
? delimiters參數指向一個字符串,定義了用作分隔符的字符集合(其中全是分隔符)
? 第一個參數指定一個字符串,它包含了0個或者多個由delimiters字符串中一個或者多個分隔符分割的標記。
? strtok函數找到str中的下一個標記(字符段:被分割符切下來的),并將其用’\0‘結尾(即用'\0'代替那個被找到的分割符),返回一個指向這個標記的指針(就是返回一個指向這個分隔符前面的那個字符段的首字符的地址。例如:給一個這樣的字符串"314.15",會返回的是314這個字符段3的地址)。(注: strtok函數會改變被操作的字符串,所以在使用strtok函數切分的字符串一般都是臨時拷貝的內容并且可修改。)
? strtok函數的第一個參數不為 NULL時 ,函數將找到str中第一個標記,strtok函數將保存它在字符串中的位置。
? strtok函數的第一個參數為 NULL時 ,函數將在同一個字符串中被保存的位置開始,查找下一個標記。
? 如果字符串中不存在更多的標記,則返回 NULL 指針。?
strtok的使用
根據這個特點,我們就可以聯想到循環來實現。?
#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "3.1415.9265.35.";char arr2[] = ".";char* ret = 0;// 循環初始化 限制條件 調整循環變量for (ret = strtok(arr1, arr2); ret != NULL; ret = strtok(NULL, arr2)){printf("%s\n", ret);}return 0;
}
strerror函數的使用?
函數原型:
//錯誤報告函數
char * strerror ( int errnum );
C語言的庫函數,在執行失敗的時候,都會設置錯誤碼。
strerror函數可以把參數部分錯誤碼對應的錯誤信息的字符串地址返回來。 在不同的系統和C語言標準庫的實現中都規定了一些錯誤碼,一般是放在 errno.h 這個頭文件中說明的,C語言程序啟動的時候就會使用一個全局變量errno來記錄程序的當前錯誤碼,只不過程序啟動的時候errno是0,表示沒有錯誤,當我們在使用標準庫中的函數的時候發生了某種錯誤,就會生成對應的錯誤碼,存放在errno中,而一個錯誤碼的數字是整數很難理解是什么意思,所以每一個錯誤碼都是有對應的錯誤信息的。strerror函數就可以將錯誤對應的錯誤信息字符串的地址返回,然后我們在用printf函數來打印就好了。?
strerror的使用?
#include <stdio.h>
#include <string.h>
int main()
{for (int i = 0; i <= 10; i++){printf("%s\n", strerror(i));}return 0;
}
Windows11+VS2022環境下輸出:?
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{//打開文件的函數是fopen,打開成功,返回一個有效的地址;//打開失敗,就返回一個空指針FILE* pf = fopen("test.txt", "r");if (pf == NULL){printf("%s\n", strerror(errno));}return 0;
}
如果要打開這個文件的話,這個文件所處的位置是要在和這個代碼文件一個目錄下。如果想要在其它路徑下找到,就得寫絕對路徑(不知道沒關系,后期會講!)。
上一期以及上面的這些都是與字符串相關的函數,下面我們就開始學習與字符相關的函數。
字符分類函數
我們在鍵盤上敲出的都是字符,但是字符也有分類。比如:空白字符,大寫字母,小寫字母,十進制數字,十六進制數字……
這些函數都是非常類似的,使用時,需要包含的頭文件都是<ctype.h>。就拿一個函數islower來舉例吧。
函數原型:
int islower ( int c );
islower 是能夠判斷參數部分的 c 是否是小寫字目的。通過返回值來說明是否是小寫字目,如果是小寫字目就返回非0的整數,如果不是小寫字目,則返回0。?
#include <stdio.h>
#include <ctype.h>
int main()
{printf("%d\n", islower('w'));printf("%d\n", islower('W'));return 0;
}
練習:寫一個代碼,將字符串中的小寫字母轉大寫,其他字符不變。
#include <stdio.h>
#include <ctype.h>
int main()
{char ch = 0;int n = 0;while (n = getchar()){//都可以實現,判斷是小寫字母if (islower(n))//if (n >= 97 && n <= 122){n -= 32;}putchar(n);}return 0;
}
getchar與putchar函數用法的講解:帶你掌握getchar與putchar的基本用法-CSDN博客?
字符轉換函數?
C語言提供了2個字符轉換函數:
int tolower ( int c ); //將參數傳進去的?寫字?轉小寫
int toupper ( int c ); //將參數傳進去的小寫字?轉大寫
有了字符轉換函數就可以直接將字符串中的小寫字母轉大寫,其他字符不變。
#include <stdio.h>
#include <ctype.h>
int main()
{char ch = 0;int n = 0;while (n = getchar()){if (islower(n))//if (n >= 97 && n <= 122){n = toupper(n);//n -= 32;}putchar(n);}return 0;
}
好啦!本期的字符函數與字符串函數到此結束!我們下期再一起學習吧!?