string.h
目录
string.h介绍1.strlen()一般使用模拟实现 2.strcpy()一般使用模拟实现 3.strncpy()一般使用 4.strcat()一般使用模拟实现 5.strncat()一般使用 6.strcmp()一般使用模拟实现 7.strncmp()一般使用 8.strstr()一般使用模拟实现 9.strtok()一般使用 10.strerror()一般使用 11.memcpy()一般使用模拟实现 12.memmove()一般使用模拟实现 13.memcmp()一般使用模拟实现 14.memset()一般使用介绍
<string.h>是C语言标准库一个常用的头文件,在使用时我们要引入头文件(#include <string.h>)常用来做字符串的处理,比较……,本文介绍了比较常用的函数
1.strlen()
一般使用
函数原型:size_t strlen ( const char * str );
//返回str的长度#include <stdio.h>#include <string.h>int main(){char arr[] = {'1','2','3'};int len1 = strlen(arr); //int len1 = my_strlen(arr);//模拟实现printf("%d\n", len1);//得到的结果是3return 0;}
模拟实现
int my_strlen(const char* str)//const 能够让代码更加健壮{int count = 0;assert(str != NULL);//判断str的首元素地址是否为NULL,是则直接退出,需要引用头文件<assert.h>while(*str != '\0')//字符串的结束标识为'\0',当没有遇到'\0'时执行{count++;//长度+1str++;//进入下一个元素地址}return count;}
2.strcpy()
一般使用
函数原型:char * strcpy ( char * destination, const char * source );
返回的是destination的地址
#include <stdio.h>#include <string.h>int main(){char arr[20] = {0};strcpy(arr, "hello");//strcpy()的结束标识为'\0'//my_strcpy(arr, "hello");//模拟实现printf("%s\n",arr);//打印结果为:helloreturn 0;}
模拟实现
char * my_strcpy(char * dst,const char * src){assert(src);//判断src的首元素地址是否为NULL,是则直接退出,需要引用头文件<assert.h>while(*src != '\0')//src指向的元素不为'\0'时执行,'\0'为结束标志{*dst++ = *src++;//src所指向元素赋值给dst所指向元素,++进入下一个元素位置}return dst;//返回dst数组首元素地址}
3.strncpy()
函数原型:char * strncpy ( char * destination, const char * source, size_t num );
返回的是destination的地址
一般使用
#include <stdio.h>#include <string.h>int main(){char arr1[20] = "abcdefhjk";char arr2[20] = "lkjhgg";char arr3[] = "qwer";strncpy(arr1,arr3,4);//将前4个字符复制到arr1中strncpy(arr2,arr3,5);//第5个字符为'\0',printf遇'\0'打印结束,arr2变成"qwer\0g"只显示前4个字符printf("%s\n",arr1);printf("%s\n",arr2);return 0;}
结果如下:
4.strcat()
函数原型:char * strcat ( char * destination, const char * source );
返回的是destination的地址
strcat不能给自己追加
一般使用
#include <stdio.h>#include <string.h>int main(){char arr[] = "hello ";char arr2[] = "world";strcat(arr, arr2);//my_strcat(arr,arr2);//模拟实现printf("%s\n", arr);return 0;}
结果如下:
模拟实现
char* my_strcat(char* dest, const char* source)//自定义函数{char* ret = dest;//dest首元素地址给指针变量retassert(dest && source);//判断dest和source是否为NULL,有任意一个为NULL则退出,需要引用头文件<assert.h>while(*dest != '\0')//解引用,访问当前地址元素,若不为'\0'则执行{dest++;//进入下一个元素地址}while (*dest++ = *source++)//从dest'\0'的位置开始将source的元素依次传给dest直到遇到source'\0'的位置{;}return ret;//返回dest起始位置的地址}
5.strncat()
一般使用
函数原型:char * strncat ( char * destination, const char * source, size_t num );
#include <stdio.h>#include <string.h>int main(){char arr1[20] = "hello";char arr2[] = "world";strncat(arr1,arr2,3);printf("%s\n",arr1);return 0;}
结果如下:
6.strcmp()
函数原型:int strcmp ( const char * str1, const char * str2 );
比较的是两个字符串对应字符的ASCII码值
如果(str1>str2)返回一个(>0)的数
如果(str1=str2)返回一个(=0)的数
如果(str1<str2)返回一个(<0)的数
一般使用
#include <stdio.h>#include <string.h>int main(){int ret = strcmp("abc", "abb");// int ret = my_strcmp("abc", "abb");//模拟实现printf("%d", ret);return 0;}
结果如下:
"abc"最后一个字符‘c’的ASCII值大于"abb"最后一个字符‘b’,返回一个大于0的数字
模拟实现
int my_strcmp(const char*a, const char*b){assert(a && b);//判断a和b是否为NULL,有任意一个为NULL则退出,需要引用头文件<assert.h>while(*a == *b)//如果对应字符相等执行{if(*a == '\0')//如果两个数相等则返回0{return 0;}a++;//进入a字符串下一个字符的地址b++;//进入b字符串下一个字符的地址}return *a - *b;//返回两个字符ASCII码值相减的结果}
7.strncmp()
函数原型int strncmp ( const char * str1, const char * str2, size_t num );
一般使用
#include <stdio.h>#include <string.h>int main(){char arr1[20] = "abcdef";char arr2[20] = "abcqef";int ret1 = strncmp(arr1, arr2, 3);int ret2 = strncmp(arr1, arr2, 4);printf("%d %d",ret1, ret2);return 0;}
结果如下:
8.strstr()
函数原型:char * strstr ( const char *, const char * );
寻找str2是否在str1中出现,出现则返回地址
一般使用
#include <stdio.h>#include <string.h>int main(){char arr1[20] = "abcedefghi";char arr2[20] = "defg";char * ret = strstr(arr1, arr2);//需要一个指针变量来接收返回的地址// char * ret = my_strstr(arr1,arr2);//模拟实现if(ret == NULL){printf("没有找到");}else{printf("%s",ret);//打印字符串}return 0;}
结果如下:
模拟实现
char * my_strstr(const char * str1, const char*str2){assert(str1 && str2);//判断str1和str2是否为NULL,有任意一个为NULL则退出,需要引用头文件<assert.h>const char*s1 = NULL;//设置指针变量s1为空指针const char*s2 = NULL;//设置指针变量s2为空指针const char*cp = str1;//将str1首元素地址赋给指针变量cpif(*str2 == '0'){return (char*)str1;//如果str2没有元素,直接返回str1的地址}while(*cp){s1 = cp;//将指针变量cp的值赋给指针变量s1s2 = str2;//将指针变量str2的值赋给指针变量s2while(*s1 && *s2 &&*s1 == *s2)//当s1,s2不为'\0'且s2和s1值相等{s1++;//进入到s1字符串下一个元素的地址s2++;//进入到s2字符串下一个元素的地址 }if(*s2=='\0'){return (char*)cp;//如果s2结束返回指针变量cp}cp++;//进入下一个元素}return NULL;//找不到则返回NULL}
9.strtok()
函数原型:char * strtok ( char * str, const char * delimiters );
如果找到标记delimiters,则指向标记开头的指针
一般使用
#include <stdio.h>#include <string.h>int main(){char arr[] = "abc@";char *p = (char*)"@.";//设置标记char temp[20] = {0};strcpy(temp, arr);//将arr数组元素复制到temp数组内char* ret = NULL; //定义ret为空指针//abc\0qq\0com//实质上是把标记字符改为'\0'for(ret = strtok(temp,p);ret != NULL;ret = strtok(NULL,p))//循环语句{printf("%s\n",ret);}return 0;}
10.strerror()
函数原型:char * strtok ( char * str, const char * delimiters );
strerror将错误码转换成错误信息,需要printf
此外,可以使用perror()直接打印错误信息(包含了自定义信息),不需要printf
一般使用
#include <stdio.h>#include <string.h>#include <error.h>char * strerror (int errnum);int main(){FILE *pf = fopen("test.txt", "r");//打开文件//0 no errorif (pf == NULL)//找不到{printf("%s\n",strerror(errno));//int errno 全局变量返回错误码perror("fopen");return 1;}return 0;}
结果如下:
11.memcpy()
函数原型:void * memcpy ( void * destination, const void * source, size_t num );
从 source 指定的内存块中复制 num 个字节到 destination 指定的内存块中
返回的是指针变量destination
复制的是字节,需要注意数据类型
不能复制source自身的字符串
一般使用
#include <stdio.h>#include <string.h>int main(){int arr1[10] = {1,2,3,4,5,6,7,8,9,10};int arr2[10] = {0};int i = 0;memcpy(arr2, arr1, 20);//20个字节,int类型4个字节一个元素,复制了5个元素//my_memcpy(arr2, arr1,20);//模拟实现 for(i = 0;i < 10;i++){printf("%d",arr2[i]);}return 0;}
结果如下:
模拟实现
void * my_memcpy(void * dst, const void * src, size_t num){assert(dst && src);//判断dst和src是否为NULL,有任意一个为NULL则退出,需要引用头文件<assert.h>void* ret = dst;//void类型指针ret存放dst数组首元素地址while(num--)//num不为0时一直递减{*(char*)dst = *(char*)src;//强制类型转化为char类型,一个字节一个字节访问dst = (char*)dst +1;//目标地址进入下一个字节src = (char*)src +1;//源地址进入下一个字节}return ret;}
12.memmove()
函数原型:void * memmove ( void * destination, const void * source, size_t num );
跟memcpy()不同的地方在于memmove()可以复制source内部的字符串
一般使用
#include <stdio.h>#include <string.h>int main(){int i = 0;int arr[10] = {1,2,3,4,5,6,7,8,9,10};memmove(arr+4, arr,20);//从arr数组第1个元素开始替换20个字节(5个元素)到arr数组第5个元素// my_memmove(arr+4,arr,20);//模拟实现for(i = 0;i < 10;i++){printf("%d",arr[i]);}return 0;}
结果如下:
模拟实现
void * my_memmove(void * dst, const void * src, size_t num){assert(dst && src);//判断dst和src是否为NULL,有任意一个为NULL则退出,需要引用头文件<assert.h>void * ret = dst;if(dst < src){//前->后while(num--){*(char*)dst = *(char*)src;//强制类型转化为char类型,一个字节一个字节访问dst = (char*)dst +1;//目标地址进入下一个字节src = (char*)src +1;//源地址进入下一个字节}}else{//后->前while(num--){*((char*)dst+num)=*((char*)src+num);}}return ret;}
原理如下:
13.memcmp()
函数原型:int memcmp ( const void * ptr1, const void * ptr2, size_t num );
效果跟strcmp()类似
如果(str1>str2)返回一个(>0)的数
如果(str1=str2)返回一个(=0)的数
如果(str1<str2)返回一个(<0)的数
一般使用
#include <stdio.h>#include <string.h>int main(){float arr1[] ={1.0,2.0,3.0,4.0};float arr2[] ={1.0,3.0,5.0,};int ret = memcmp(arr1,arr2,8);//比较两个数组前8个字节的元素// int ret = my_memcmp(arr1,arr2,8);//模拟实现printf("%d",ret);return 0;}
结果如下:
模拟实现
int my_memcmp(const void* str1, const void* str2, size_t num){assert(str1 && str2 && num != 0);//判断str1和str2是否为NULL,num的值不为0,有任意一个为NULL则退出,需要引用头文件<assert.h>while(num --){if(*(char*)str1 != *(char*)str2)//将str1,str2强制转化为char类型指针,方便一个字节一个字节访问{return (*(char*)str1) - (*(char*)str2);//返回差值}str1 = (char*)str1 +1;//进入下一个字节地址str2 = (char*)str2 +1;//进入下一个字节地址}return 0;//相等返回0}
14.memset()
函数原型:void * memset ( void * ptr, int value, size_t num );
一般使用
#include <stdio.h>#include <string.h>int main(){//arr数组共有40个字节int arr[10] = {0};int i = 0;memset(arr,1,20);//前20个字节设置为1,实际效果为0000000001010101for(i = 0;i<10;i++){printf("%p\n",arr[i]);}return 0;}
结果如下:
如果觉得《C语言字符串函数<string.h>(部分)》对你有帮助,请点赞、收藏,并留下你的观点哦!