4.strcmp
(1)strcmp库函数文档
1.这个函数有两个参数都是const char*类型的,因为我们不会进行修改,我们只会进行查看
2.这个函数的作用是比较两个字符串的大小,比较规则是:从第一个字符依次开始比较,一个字符一个字符比较,谁的ASCII码值大,谁就大。如果相等则比较后一个字符。
3.这个函数的返回值是int类型,如果str1大于str2,则返回一个大于0的数,如果相等则返回0,如果小于则返回小于0的一个数
4.在vs环境下:大于返回1,等于返回0,小于返回-1。但是在其他编译器上不一定成立
(2)strcmp的使用
#include<stdio.h> #include<string.h> int main() { char arr1[] = "abcdef"; char arr2[] = "abc"; int ret = strcmp(arr1, arr2); printf("%d\n", ret); return 0; }
(3)strcmp的模拟实现
#include<stdio.h> #include<assert.h> int my_strcmp(const char* str1, const char* str2) { assert(str1 && str2); while (*str1 == *str2) { if (*str1 == '\0') { return 0; } str1++; str2++; } if (*str1 > *str2) { return 1; } else { return -1; } //在一些编译器上是这样实现的 //return *str1 - *str2; } int main() { char arr1[] = "abcefg"; char arr2[] = "abc"; int ret = my_strcmp(arr1, arr2); printf("%d\n", ret); return 0; }
注意事项(函数不安全的原因)
strcpy,strcat,strcmp这些函数都是不安全的函数,因为他们都是长度不受限制的函数,如果目标空间不是很大,则会出现问题。所以我们vs上使用这些函数需要使用开头的那个预处理指令
#define _CRT_SECURE_NO_WARNINGS 1
而为了让这些更安全,我们就有了strncpy,strncat,strncmp这些长度受限制的函数
5.strncpy
(1)strncpy库函数文档
这个函数有三个参数,char* destination,const char* source和size_t num,前两个参数的意思是目标空间的地址和源头的地址,num的意思是要拷贝几个字节
意思是拷贝前num个字节到destination中
返回类型是char*返回destination的地址
(2)strncpy的使用以及注意事项
1.拷贝num个字符从源字符串到目标空间。
2.如下图1所示,如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
3.如下图2所示,我们在使用的时候要注意,不会将最后的\0给拷贝进来,需要拷贝几个字符就拷贝几个字符.
(3)strncpy的模拟实现
需要注意的事项是,由于拷贝受两个条件控制
如果num为0导致的结束的话,也就是拷贝了一部分,那么我们就不会补充\0
如果是由于源头字符串拷贝完了,但是num还没结束导致的结束,那么我们就要补充\0,要注意我们这个num是少减了一次1的,所以要前置--
第一个循环中,num和赋值的操作是不可以进行交换顺序的,这是因为&&的短路现象
#include<stdio.h> #include<assert.h> char* my_strncpy(char* dest, const char* src, size_t num) { assert(dest && src); char* ret = dest; while (num && (*dest++ = *src++)) { num--; } if (num) { while (--num) { *dest++ = '\0'; } } return ret; } int main() { char arr[] = "xxxxxxxxxxxxxxxxxxxxx"; char* p = my_strncpy(arr, "hello", 10); printf("%s\n", p); return 0; }
6.strncat
(1)strncat的库函数文档
这个的参数和返回类型与strncpy是一样的
不同的是函数的功能是追加source的前n的字符
这前n个字符追加后是需要补充一个\0的
(2)strncat的使用以及注意事项
1.对于这个函数,我们需要注意的就是追加之后后面会补充一个\0的
2.即便超出了source的范围,也只是补一个\0,不会补充多个\0
#include<stdio.h> #include<string.h> int main() { char arr[] = "xxx\0xxxxxxxxxxxxxxx"; char* p = strncat(arr, "hello", 3); return 0; }
#include<stdio.h> #include<string.h> int main() { char arr[] = "xxx\0xxxxxxxxxxxxxxx"; char* p = strncat(arr, "hello", 10); return 0; }
(3)strncat的模拟实现
#include<stdio.h> #include<assert.h> char* my_strncat(char* dest, const char* src, size_t num) { assert(dest && src); char* ret = dest; while (*dest != '\0') { dest++; } while (num--) { if ((*dest++ = *src++) == '\0') { return ret; } } *dest = '\0'; return ret; } int main() { char arr[] = "xxx\0xxxxxxxxxxxxxxx"; char* p = my_strncat(arr, "hello", 3); return 0; }
7.strncmp
(1)strncmp的库函数文档
函数的功能是比较前n个字符的大小,返回一个值。
如果str1大,则返回大于0的数
如果str2大,则返回小于0的数
如果相等,则返回0
(2)strncmp的使用
比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完
#include<stdio.h> #include<string.h> int main() { char* p1 = "abcdef"; char* p2 = "abcfda"; int ret = strncmp(p1, p2, 3); printf("%d\n", ret); return 0; }
#include<stdio.h> #include<string.h> int main() { char* p1 = "abcdef"; char* p2 = "abcfda"; int ret = strncmp(p1, p2, 4); printf("%d\n", ret); return 0; }
#include<stdio.h> #include<string.h> int main() { char* p1 = "abdef"; char* p2 = "abcfda"; int ret = strncmp(p1, p2, 4); printf("%d\n", ret); return 0; }
8.strstr
(1)strstr库函数文档
这个函数有两个参数,都是const char* 类型的
功能是子str1中查找是否存在str2字符串
返回一个const char* 类型的地址,如果存在,则返回在str1中第一次出现str2的地址,如果不存在,则返回NULL
(2)strstr的使用
#include<stdio.h> #include<string.h> int main() { char arr1[] = "abcdef"; char arr2[] = "bcd"; const char* ret = strstr(arr1, arr2); if (ret != NULL) { printf("%s\n", ret); } else { printf("找不到\n"); } return 0; }
#include<stdio.h> #include<string.h> int main() { char arr1[] = "abcdef"; char arr2[] = "bcdf"; const char* ret = strstr(arr1, arr2); if (ret != NULL) { printf("%s\n", ret); } else { printf("找不到\n"); } return 0; }
(3)strstr的模拟实现
我们在这里采用的是暴力循环遍历的方法。当然也可以使用KMP算法,在此不做介绍了
#include<stdio.h> #include<assert.h> char* my_strstr(const char* str1, const char* str2) { assert(str1 && str2); if (*str2 == '\0') { return (char*)str1; } const char* s1 = NULL; const char* s2 = NULL; const char* cp = str1; while (*cp) { s1 = cp; s2 = str2; while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) { s1++; s2++; } if (*s2 == '\0') { return cp; } cp++; } return NULL; } int main() { char arr1[] = "abcdef"; char arr2[] = "bcdef"; char* ret = my_strstr(arr1, arr2); if (ret != NULL) { printf("%s\n", ret); } else { printf("找不到\n"); } return 0; }
9.strtok
(1)strtok的库函数文档
这个函数有两个参数,str是目标字符串。它是需要被修改的
delimiters是一个字符串,定义了用作分隔符的集合
函数的功能是,在str字符串中找到,delimiter这个集合中的任意一个字符,然后将最先出现的这个字符修改为\0,并且返回分割好的这个字符串的地址,并且内部有一个静态变量记录之前切割的位置
这个str可以是一个null,如果传的是空指针的话,那么就在后面的字符串中找到集合中的某个元素,并且修改为\0,然后返回这个字符串。
(2)strtok的使用以及注意事项
第二个参数sep是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由第二个字符串sep中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL 指针。
#include<stdio.h> #include<string.h> int main() { char arr[] = "192.168.120.86#56789"; char sep[] = ".#"; char buf[30] = { 0 }; strcpy(buf, arr); char* ret = NULL; for (ret = strtok(buf, sep); ret != NULL; ret = strtok(NULL, sep)) { printf("%s\n",ret); } return 0; }
10.strerror
(1)strerror的库函数文档
这个函数它会接受一个整型的数字,这个数字是一个错误码,然后返回一个字符串的地址,我们可以打印出这个字符串的地址,显示我们的错误信息
C语言在运行时,如果发生错误,就会将错误码存放到errno
这个变量中,而这个函数可以将错误码翻译成字符串