關於字串的功能函式小結

Rice_rice發表於2024-05-25

筆者做專案過程中,使用了很多關於字串的C庫中自帶功能函式,極大便利了專案流程。再次做一個小結,之後若有增加會繼續補充。

所需採用函式

序號 函式/描述
1 char *strcat(char *dest, const char *src) 【char *strncat(char *dest, const char *src, size_t n)】
功能:連線兩個字串【連線至多n個位元組的字串】
dest目標字串,src源字串
返回值:返回目標字串dest的指標
用法詳見例1
2 int strcmp(const char *s1, const char *s2)【int strncmp(const char *s1, const char *s2, size_t n)】
功能:比較兩個字串【比較至多n個位元組的字元】
s1目標字串,s2源字串,n 位元組數量
返回值:如果分別發現s1(或其前n個位元組)小於、等於或大於s2,則返回一個小於、等於或大於零的整數。
用法詳見例2
3 char *strcpy(char *dest, const char *src)【char *strncpy(char *dest, const char *src, size_t n)】;
功能:複製兩個字串【複製至多n個位元組的字元】
dest目標字串,src源字串
返回值:返回目標字串dest的指標
用法詳見例3
4 char *strstr(const char *haystack, const char *needle)【char *strchr(const char *s, int c); char *strrchr(const char *s, int c);】;
功能:定位字串中的子串【定位字串的字元】
haystack目標字串,needle子串指標
返回值:strstr函式返回指向找到的子字串開頭的指標,如果找不到子字串,則返回NULL。【strchr返回指向首次找到字元c的字元開頭的指標; strrchr返回指向最後依次找到字元c的字元開頭的指標;】
5 char *strtok(char *str, const char *delim);【char *strtok_r(char *str, const char *delim, char **saveptr)】;
功能:從字串中提取令牌(此處的令牌可理解為每個被分割的子串)
在第一次呼叫時,str是一個指向要分割的字串的指標。在後續的呼叫中,它應該為 NULL,因為 strtok() 會內部儲存上次呼叫時的位置。
delim指向一個字串的指標,該字串包含了用於分隔 str 的所有字元。
str目標字串,delim一個包含分隔符的字串。strtok 會根據這個字串的每一個分隔符來分割 str
使用 strtok()strtok_r() 後,原始字串 str 會被修改,因為這兩個函式會在找到的每個令牌後插入一個空字元('\0')來終止它。
返回值:每次都會返回'\0'前面的值。
用法詳見例4
6 char *strerror(int errnum);
功能:這個函式接受一個錯誤號作為引數,並返回一個指向描述該錯誤的字串的指標。
(用的比較少,後面再補充用法與perror有相同之處)
7 int atoi(const char *nptr);【 long atol(const char *nptr)】【long long atoll(const char *nptr)】;
功能:把字串轉為整型(長整型/長長整型),從字串的開頭開始解析整數,直到遇到非數字字元為止。
用法詳例5
8 double strtod(const char *nptr, char **endptr);【float strtof(const char *nptr, char **endptr)】;
功能:把字串轉為浮點型
nptr 所指向的字串用法詳例子;endptr 會被設定為指向在 nptr 中首次出現不能轉換為數字的字元的指標。
9 size_t strlen(const char *s);【size_t strnlen(const char *s, size_t maxlen);】
功能:計算字串長度【strnlen() 函式只會檢視從 s 指向的字串開始的最多 maxlen 個字元。】
10 char *strsep(char **stringp, const char *delim)
功能:功能與strtok類似,有幾點區別:
(1)strtok是C標準庫中的一個函式,它在POSIX標準中也有定義。這意味著它在各種C和C++編譯器中都可用,並且其行為是標準化的。然而,strsep並不是C標準或POSIX標準的一部分,而是GNU C庫(glibc)中的一個函式,起源於BSD。
(2)執行緒安全性。
(3) strsep引數不能用NULL
strsep和strtok在功能上是相似的,但在標準化程度、執行緒安全性、連續分隔符的處理、返回值和引數型別等方面存在差異,需要更深一步學習
用法詳見例4

例1:strcat&strncat

#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{

	char str1[100] = "Hello";//此處一定要申請一個足夠空間的變數,存放str2
	char *str2 = "world";
	strcat(str1, str2);
	printf("change str1 for [%s]\n", str1);

	strncat(str1, str2, 4);
	printf("change str1 for [%s]\n", str1);

	return 0;
}
//輸出結果
change str1 for [Helloworld]
change str1 for [Helloworldworl]

例2:strcmp

int main(int argc, char const *argv[])
{

	char str1[100] = "Hello";
	char *str11 = "Hello";
	char *str2 = "Hell";
	char *str3 = "Hello";
	char *str4 = "Hello1";
	printf("result of compare str1 and str2:%d \n", strcmp(str1, str2));
	printf("result of compare str11 and str2:%d \n", strcmp(str11, str2));
	printf("result of compare str1 and str3:%d \n", strcmp(str1, str3));
	printf("result of compare str11 and str3:%d \n", strcmp(str11, str3));
	printf("result of compare str1 and str4:%d \n", strcmp(str1, str4));
	printf("result of compare str11 and str4:%d \n", strcmp(str11, str4));
	return 0;
}
//輸出結果
result of compare str1 and str2:111
result of compare str11 and str2:111
    //得出結論,陣列和字串常量指標可以直接比較
    //str1大於str2,輸出大於0,str1等於於str3,輸出0,str1小於str4,小於0,
result of compare str1 and str3:0
result of compare str11 and str3:0
result of compare str1 and str4:-49
result of compare str11 and str4:-49

例3:strcpy&strncpy

int main()
{
	char str1[100] = "Hello the world";//此處一定要申請一個足夠空間的變數,存放str2
	char *str2 = "world";
	char str11[100] = "Hello the world";//此處一定要申請一個足夠空間的變數,存放str2
	char *str22 = "world";
	strcpy(str1, str2);
	printf("copy str1 for [%s]\n", str1);
	strncpy(str11, str22, 4);
	printf("ncopy str1 for [%s]\n", str11);
	return 0;
}
//輸出結果 
//得到結論,strcpy複製整個源字串並且會自動新增\0,
//但strncpy不會自動新增\0,如果str1長度大於str2,則只會替換前n個字元,後面的照常
copy str1 for [world]
ncopy str1 for [worlo the world]

例4:strtok&strsep

int main()
{

	char student_info[100] = "姓名:李四|性別:男|電話號碼:123456789|身份證號碼:987654321"; // 以':'和'|'為分隔符分割資訊
	char *tmp = NULL;
	tmp = strtok(student_info, ":"); // 得到第一個“令牌”,即將遇到的第一個‘:’變成‘\0’,tmp得到的是 “姓名”
	int i = 1;
	while (tmp != NULL)
	{
		printf("遇到的第%d次分隔符分割結果:%s\n", i, tmp);
		i++;
		tmp = strtok(NULL, ":|"); // // 得到後續“令牌”,即將遇到的後續的‘:’或者‘|’都改成‘\0’,並返回前值。
	}
	printf("student_info變成:%s\n", student_info); // 原始的字串會被改變,被第一次使用的分隔符分割,後面的被‘\0’隔斷

	char student_info2[100] = "姓名:李四|性別:男|電話號碼:123456789|身份證號碼:987654321"; // 以':'和'|'為分隔符分割資訊
	char *tmp2 = NULL;
	char *strsep_test = student_info2;
	tmp2 = strsep(&strsep_test, ":"); // 得到第一個“令牌”,即將遇到的第一個‘:’變成‘\0’,tmp得到的是 “姓名”
	i = 1;
	while (tmp2 != NULL)
	{
		printf("strsep第%d次分割結果:%s\n", i, tmp2);
		i++;
		tmp2 = strsep(&strsep_test, ":|"); // // 得到後續“令牌”,即將遇到的後續的‘:’或者‘|’都改成‘\0’,並返回前值。
	}
	printf("student_info變成:%s\n", student_info2); // 原始的字串會被改變,被第一次使用的分隔符分割,後面的被‘\0’隔斷

	return 0;
}

//輸出結果
遇到的第1次分隔符分割結果:姓名
遇到的第2次分隔符分割結果:李四
遇到的第3次分隔符分割結果:性別
遇到的第4次分隔符分割結果:男
遇到的第5次分隔符分割結果:電話號碼
遇到的第6次分隔符分割結果:123456789
遇到的第7次分隔符分割結果:身份證號碼
遇到的第8次分隔符分割結果:987654321
student_info變成:姓名
strsep第1次分割結果:姓名
strsep第2次分割結果:李四
strsep第3次分割結果:性別
strsep第4次分割結果:男
strsep第5次分割結果:電話號碼
strsep第6次分割結果:123456789
strsep第7次分割結果:身份證號碼
strsep第8次分割結果:987654321
student_info變成:姓名

例5:atoi, atol, atoll,strtod, strtof

int main()
{
	char *str = "123hello";

	printf("%d %ld %lld\n", atoi(str), atol(str), atoll(str)); // 遇到非數字就停止,因此輸出123
	char *str1 = "123.456hello";
	char *endptr;

	printf("strtod:%f strtof:%f \n", strtod(str, &endptr), strtof(str, NULL));
	printf("接收的首次遇到非數字後面的字元段:%s\n", endptr);
	return 0;
}

//輸出結果
123 123 123
strtod:123.000000 strtof:123.000000
接收的首次遇到非數字後面的字元段:hello

另外筆者還使用過與記憶體塊處理相關的一些函式,例如memchrmemcmpmemmovememsetmemcpy對於處理字串也很有用。memchr 用於在記憶體塊中查詢字元,memcmp 用於比較記憶體塊,memmove 用於複製記憶體塊(可能重疊),而memset 用於設定記憶體塊的值,memcpy 用於複製記憶體塊的值。後續可能重新整理關於這塊內容。

相關文章