绪论
书接上回,通过进阶指针你已经了解到了更多种指针类型,他们的用法及使用之处相当的关阔需要不断的积累经验来使用,这里我毛遂自荐一下我的指针练习希望对你有帮助,本章是一些关于字符串的函数介绍和自己实现,总体来说学会了这些函数可以对你在字符串类型的编程有很大的意义。
所以安全带系好,发车啦(建议电脑观看)。
思维导图:
要XMind思维导图的话可以私信哈
目录
1.函数介绍
1.1strlen
1.2strcpy
1.3strcat
1.4strcmp
1.5 strncpy
1.6strncat
1.7strncmp
1.8strstr
1.8strtok
1.9strerror
1.10字符分类函数
1.11memcpy
1.12memmove
1.13memcmp
1.14memset
1.函数介绍
下面将介绍到如下库函数:
求字符串长度型:
strlen
字符串函数型:
strcpy : copy :拷贝型
strcat :catch:追加型
strcmp :compare:比较型
strncpy : 拷贝型 加num确定了拷贝的个数
strncat:同上确定了追加的个数
strncmp:同理
字符串查找型:
strstr :在str(前)字符串中查是否有str(后)
strtok:在str中找分隔符(token)
返回错误型:
strerror
内存函数型(与字符串功能类似):
memcpy
memmove
memset
memcmp
1.1strlen
知识点:
size_t strlen (const char * string)
这个函数是求字符串长度的,从所传递进来的地址开始以char * 的步长往后找 '\0'
最终返回无符号的\0前的共有的元素个数
细节(注意点):
因为strlen以'\0'为结束标志,所以在其算的字符串中必须得有'\0',否则将会算出一个随机值
练习:
char arr[] = "abce"; int ret = strlen(arr); printf("%d\n",ret);//4
模拟实现strlen
1.2strcpy
知识点:
char * strcpy(char * destination , const char * source )
将source处的字符串拷贝到destination处的空间内
返回des的起始地址
细节:
source内必须有\0来结束拷贝
destination的空间必须要大于等于source拷贝过来所需的大小
在拷贝时source内的\0也会被拷贝过来
destination处的空间必须是可修改的
练习:
char arr1[] = "xxxxxxxxxxxxxxxx"; char arr2[] = "abcdef"; printf("%s",strcpy(arr1,arr2));//strcpy返回的是arr1首元素的地址,所以最终将打印abcdef //当如下时 char arr2[] = "ab\0cdef"; printf("%s",strcpy(arr1,arr2));//strcpy返回的是arr1首元素的地址,所以最终将打印ab \0看不到
模拟实现strcpy
1.3strcat
知识点:
char * strcat(char * destination , const char * source )
其用法和strcpy有点类似,是将source内的数据追加到destination后面去
返回des的起始地址
细节:
source内必须有\0停止
destination必须有足够的空间放
destination内也必须有\0否则无法进行拷贝
destination必须可以被修改
不能自己给自己追加(因为是从\0开始追加所以\0会别取代,这样就无法停止)
练习:
char arr1[] = "hello "; char arr2[] = "world"; //char *arr2 = "world"; printf("%s",strcat(arr1,arr2));//最终打印hello world //从\0处开始,如果arr1 he\0llo -> heworld
strcat的模拟实现
1.4strcmp
知识点:
int strcmp(const char * str1 , const char * str 2)
比较两个字符串的大小
返回值:
str1 > str2 返回大于0的数
1 < 2 返回小于0的数
1 = 2 返回0
vs环境下1 > 2 返回 1 1 < 2 返回 -1 1=2 返回0
细节:
字符串的比较时是对应的一个个字符比较,并且比较的是对应的ASCII码值
练习:
strcmp的模拟实现
char arr1[] = "abcdef"; char arr2[] = "abq"; printf("%d",strcmp(arr1,arr2));//次处1 和 2 的前两个字符a b 的ASCII码相但是比到c 与 q 时 //c 的ASCII码值小于 q的... 所以最终 1 < 2 返回负数
对于以上的函数没有对字符的限制(只到\0才停止),所以和scanf一样并不太安全所以需要
#define _CRT_SECURE_NO_WARNINGS 1 来防止报错
以下是一些有字符个数限制的字符函数
1.5 strncpy
知识点:
char* strncpy(char * destination ,char * source,size_t num);
其用法和strcpy几乎一致只是要对拷贝的字符个数有明确限制
同样返回des的起始地址
细节:
将指定的source的字符个数拷贝到destination处,当所需拷贝的字符超过source时后面用\0替代继续拷贝
练习:
模拟实现strncpy
char * my_strncpy(char * des ,const char * sour ,size_t count) { assert(des && sour); char * tmp = des; while(count--) { if(*sour == '\0') { *des++ = '\0'; continue; } else { *des++ = *sour++; } } } //反之 char* my_strncpy(char* strDest, const char* strSource, size_t count) { assert(strDest && strSource); char *ret = strDest; while(count--) { *strDest = *strSource ; if(*strSource != '\0') { strDest++; strSource++; } } return ret; }
例子:
1.6strncat
知识点:
char * strncat(char * des , const char * sour ,size_t count)
同样用法相同,加上了限制的个数
同样返回des的起始地址
细节:
追加完后在最后补上一个\0
练习:
模拟实现strncat
char* my_strncat(char* des, const char* sour, size_t count) { assert(des && sour); char* tmp = des; while (*des) { des++; } while (count--) { if (*sour == '\0') *des = '\0'; *des++ = *sour++; } return tmp; }
例子:
1.7strncmp
知识点:
int strncmp(const char * str1 ,const char * str2 ,size_t count);
用法相同,限制了比较个数
返回值还是相同:
str1 > str2 返回大于0的数
1 < 2 返回小于0的数
1 = 2 返回0
vs环境下1 > 2 返回 1 1 < 2 返回 -1 1=2 返回0
练习:
模拟实现
int my_strncmp(const char* string1, const char* string2,size_t count) { assert(string1 && string2); while (*string1 == *string2 && *string1 != '\0')//找到不相等的字符 { if (!--count)//后置--时无法会继续往下走而导致string1 2 指向改变 { break; } string1++; string2++; } if ((*string1 - *string2) == 0) { return 0; } else { return (*string1 - *string2) > 0 ? 1 : -1; } //vs环境下1大于2返回1 , 1<2 返回-1 1 = 2 返回 0 }
1.8strstr
知识点:
char *strstr( const char *string, const char *strCharSet );
在string字符串内寻找strcharset
返回strcharset首次出现的位置
细节:
寻找时:
1.如果存在:返回找到strcharset的第一个元素的地址
2.如果不存在:返回NULL
3.如果strcharset 为空则则直接返回string的地址
练习:
模拟实现strstr
1.8strtok
知识点:
用来分割字符串的函数,char *strtok( char *strToken, const char *strDelimit );
strToken给定的一个字符串,strDelimit 传进的分隔符组
在strToken内找strDelimit 来进行分隔
返回本次分隔好后的字符串的首元素的地址
细节:
如何使用strtok:
代码展示:
结果:
总结来说就是:
首先传进要分隔的字符串,和分隔符组进行第一次分隔
其次要再次进行分隔(第一次分隔将返回首元素地址,和记录分隔后剩的字符地址),当传进NULL和分隔符组时表示继续分隔
最后若没有字符了就会返回NULL
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<string.h> int main() { char arr1[] = "ZhaoYKun@qq.com"; char arr2[]= "@."; //char arr2[] = {'@','.','\0'};//效果相同 printf("%s\n", strtok(arr1, arr2));//返回第一次分隔好的字符的首元素地址 printf("%s\n", strtok(NULL, arr2));//当用NULL时表示从分隔好了,继续从下一个开始 printf("%s\n", strtok(NULL, arr2));//同理 printf("%s\n", strtok(NULL, arr2));//当后面没有后返回NULL return 0; }