1. strncpy函数的使用和模拟实现
char* strncpy(char* destination, const char* source, size_t num)
1.1 函数功能以及用法
拷贝指定长度的字符串
将“source”指向的字符串中的“num”个字符拷贝到“destination”指向的字符数组中。相比于strcpy函数,该函数多了一个参数“num”,表示要拷贝字符的个数。这样一来,就不会因为检索不到'\0'而越界访问了,相对安全,且更加灵活。
1.2 函数的原理
在strcpy的基础之上,另外设置一个判断条件,使得当拷贝完“num”个字符之后,函数就会停止拷贝。
1.3 注意事项
如果源字符串的⻓度⼩于num,则拷⻉完源字符串之后,在⽬标的后边追加0,直到num个。
1.4 模拟实现
char* my_strncpy(char* dest, const char* src, size_t num)
{assert(dest && src);char* ret = dest;int flag = 0;while(num--){if(*dest == '\0')flag = 1;if(*src == '\0')*dest++ = *src;else*dest++ = *src++;}if(flag)*dest = '\0';return ret;
}
2. strncat函数的使用和模拟实现
char* strncat(char* destination, const char* source, size_t num)
2.1 函数功能以及用法
追加指定长度的字符串
将“source”指向的字符串中的“num”个字符追加到“destination”指向的字符数组中。相比于strcat函数,同样多了一个参数“num”。
2.2 函数的原理
在strcat的基础之上,另外设置一个判断条件,使得当追加完“num”个字符之后,函数就会停止追加。
2.3 注意事项
如果“source” 指向的字符串的⻓度⼩于“num”的时候,只会将字符串中到 '\0' 的内容追加到“destination”指向的字符串末尾,也就是不会额外补充'\0'。
2.4 模拟实现
char* my_strncat(char* dest, const char* src, size_t num)
{assert(dest && src);char* ret = dest;while(*dest != '\0'){dest++;}while(num--){*dest++ = *src++;if(*src == '\0')break;}*dest = '\0';
}
3. strcmp函数的使用和模拟实现
int strncmp(const char* str1, const char* str2, size_t num)
没什么好说的直接看模拟实现吧
int my_strncmp(const char* str1, const char* str2, size_t num)
{assert(str1 && str2);while(*str1 == *str2 && num--){if(*str1 == '\0')return 0;str1++;str2++;}return (*str1 - *str2);
}
4. strstr函数的使用和模拟实现
char* strstr(const char* str1, const char* str2)
4.1 函数的功能以及用法
查找子字符串
在“str1”指向的字符串中查找是否有“str2”指向的字符的存在。在使用时,要求用户输入两个字符串的起始位置,找到时返回str2在str1中的起始位置,找不到返回空指针。
#include <stdio.h>
#include <string.h>int main()
{char email[] = "3143884180@qq.com";char substr[] = "@qq.com";char* ret = strstr(email, substr);if(ret == NULL){printf("子串不存在\n");}else{printf("%s\n", ret);}return 0;
}
4.2 函数的原理
首先在str1中查找str2的首字符,找到之后检验紧跟着的内容是否与str2完全相同,若相同则返回该相应的地址;若不相同则继续在str1中查找str2的首字符,直到排查完str1中所有可能的位置。
4.3 注意事项
字符串的⽐较匹配不包含 '\0' 字符,以 '\0' 作为结束标志
4.4 模拟实现
char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);while(*str1)//当*str1为'\0'时循环结束,返回NULL{while(*str1 != *str2)//找到第一个字符相等的位置{str1++;if(*str1 == '\0')return NULL;}const char* str3 = str1;const char* str4 = str2;while(*str3++ == *str4++)//检查改位置是否符合条件{if(*str4 == '\0')return (char*)str1;}str1++;//未返回说明不符合,第一个指针移动一次}return NULL;
}
5.strtok函数的使用和模拟实现
char* strtok(char* str, const char* sep)
5.1 函数的功能以及用法
字符串分割
依据用户提供的分隔符,将字符串分隔为几个部分。
1. sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合
2. 第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标记。
3. strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。
4. strtok函数的第⼀个参数不为 NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置。
5. strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。
6. 如果字符串中不存在更多的标记,则返回 NULL 指针。
int main()
{const char* sep = "@.";char email[] = "3143884180@qq.com";char cp[30] = {0};strcpy(cp, email);char* ret = strtok(cp, sep);if(ret != NULL)printf("%s\n", ret);ret = strtok(NULL, sep);if(ret != NULL)printf("%s\n", ret);ret = strtok(NULL, sep);if(ret != NULL)printf("%s\n", ret);return 0;
}
如图,在sep中定义了分隔符“@”和“.”。
第一次调用,将cp的地址传入,函数在字符串“3143884180@qq.com”中找到“@”,将其替换为'\0'并返回指向“3143884180”的指针。同时,函数已经记录下这个'\0'的地址。
第二,三次调用,将NULL传入,函数通过自己记录下的位置,开始查找下一个分隔符。
该代码还可简写为
int main()
{const char* sep = "@.";char email[] = "3143884180@qq.com";char cp[30] = {0};strcpy(cp, email);char* ret = NULL;for(ret = strtok(cp, sep); ret != NULL; ret = strtok(NULL, sep)){printf("%s\n", ret);}return 0;
}
5.2 函数的原理
首先检查第一个参数是否为NULL,若是则用记录好的位置将其替换。然后在字符串中查找分隔符,将其替换为'\0'后用static修饰的变量记录并返回字符串的起始位置。
5.3 注意事项
strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串⼀般都是临时拷贝的内容并且可修改。
5.4 模拟实现
char* my_strtok(char* str, const char* sep)
{assert(sep);static char* tmp = NULL;if(str == NULL && tmp == NULL)return NULL;if(str == NULL)str = tmp + 1;char* ret = str;for(int i = 0; str[i] != '\0'; i++){for(int j = 0; sep[j] != '\0'; j++){if(str[i] == sep[j]){str[i] = '\0';tmp = str + i;return ret;}}}tmp = NULL;return ret;
}
6.strerror函数的使用
char * strerror ( int errnum )
strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。 在不同的系统和C语言标准库的实现中都规定了⼀些错误码,⼀般是放在 errno.h 这个头文件中说明 的,C语言程序启动的时候就会使用⼀个全局变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表示没有错误,当我们在使用标准库中的函数的时候发生了某种错误,就会讲对应 的错误码,存放在errno中,而⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是 有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。
#include <errno.h>
#include <string.h>
#include <stdio.h>int main()
{int i = 0;for (i = 0; i <= 10; i++) {printf("%s\n", strerror(i));}return 0;
}
0. No error-----------------------------------------无错误
1. Operation not permitted--------------------不允许操作
3. No such file or directory--------------------没有这样的文件或目录
4. No such process-----------------------------没有这样的进程
5. Interrupted function call--------------------函数调用中断
6. Input/output error----------------------------输入/输出错误
7. No such device or address----------------没有这样的设备或地址
8. Arg list too long-------------------------------参数列表太长
9. Exec format error----------------------------执行格式错误
10. Bad file descriptor--------------------------错误的文件描述符
11. No child processes-------------------------无子进程