什么网站做装修的,网站开发哪个工具,购物网站后台管理系统模板,阜阳做网站的商户穗
一些闲话#xff1a;
最近玩了这款饿殍-明末千里行#xff0c;不知大家是否有听过这款游戏#xff0c;颇有感触#xff01;#xff01;#xff01;
游戏中最让我难以忘怀的便是饿殍穗线的故事#xff0c;生在如今时代的我之前无法理解杜甫在目睹人间悲剧时的心情
最近玩了这款饿殍-明末千里行不知大家是否有听过这款游戏颇有感触
游戏中最让我难以忘怀的便是饿殍穗线的故事生在如今时代的我之前无法理解杜甫在目睹人间悲剧时的心情但现在我似乎有些能够共情了。在游戏中我以第三人称视角目睹了一个美好家庭的支离破碎的过程那种痛苦难以言表。天灾人祸饿殍遍野有人在笑有人在哭富人更富穷人死亡。 前言
本篇文章将延续上一篇继续介绍字符串函数希望能够对大家有所帮助
话不多说直接上正文
上一篇文章我们将字符串函数分为四类并介绍了strlen函数 本篇文章小编将会带着大家了解后面三类字符串函数
1、 strcpy与strncpy
1.1 strcpy的使用和模拟
1.1.1 strcpy的使用 strcpy -- string copy 字符串拷贝 这是什么意思呢 char ch1[] Hello,world;
char ch2[20]; 比如说你有一个字符串ch1想要将ch1中的内容拷贝到ch2中这时候我们就可以使用strcpy函数了 那么这个函数该怎么使用呢
函数原型
char * strcpy ( char * destination, const char * source );
我们来看一下cplusplus上是怎么说明的 也就是说destination是目标空间sourse是源头 我们将源头里的内容拷贝到目的地中在结合我们上面举的例子我们想将ch1中的内容拷贝到ch2中那么ch1便是源头ch2便是目标空间。
代码实现
#include stdio.h
#include string.h
int main()
{char ch1[] Hello,world;char ch2[20];strcpy(ch2, ch1);printf(%s\n, ch2);return 0;
} 结果展示 这便是strcpy的作用当我们学会了strcpy的使用我们还需要知道为什么知其然知其所以然 我们验证一下有没有将\0一同拷贝 char ch1[] Hello;char ch2[20] *************;//为了方便观察是否拷贝了\0strcpy(ch2, ch1); 从调试过程中我们可以发现 \0 的确是拷贝过来了。
既然strcpy会将源头内容中的\0拷贝过来那么如果源头不包含\0的话会有什么结果呢
char ch1[] { a,b,c};
char ch2[20] *************;//为了方便观察是否拷贝了\0
strcpy(ch2, ch1); 这里为什么会出现这样的错误呢 就是因为源头内容中不存在\0。没有\0 strcpy拷贝就停不下来会一直拷贝直到越界报错。 因此 strcpy函数的使用需要注意几点 源字符串必须以 \0 结束。目标空间必须足够大以确保能存放源字符串目标空间必须可修改 1.1.2 strcpy的模拟实现
当学会strcpy怎么使用后我们也可以尝试自己写一个函数来模拟一下strcpy
#include stdio.h
#include string.h
void my_strcpy(char* ch2, char* ch1)
{while (*ch1 ! \0){*ch2 *ch1;*ch2;*ch1;}*ch2 *ch1;//如果*ch1 \0,ch2 \0
}
int main()
{char ch1[] hello;char ch2[20];my_strcpy(ch2, ch1);printf(%s\n, ch2);return 0;
} 当ch1不等于 \0 的时候就继续向后寻找且令ch2 ch1 当ch1等于 \0 的时候则不再向后寻找令ch2 ch1; void my_strcpy(char* ch2, char* ch1)
{while (*ch1 ! \0){*ch2 *ch1;*ch2;*ch1;}*ch2 *ch1;//如果*ch1 \0,ch2 \0
}
上面那个模拟实现还可以进行一些优化我们可以再进行简化一下 比如说*ch2和*ch1可以与上面的合并一下
*ch2 *ch1;
后置是用完之后再所以和前面的表示是一样的。 前面我们将*ch1 分为是否等于 \0,这里也可以合并一下
void my_strcpy(char* ch2, char* ch1)
{while (*ch2 *ch1 ){;}
}
分析一下 循环结束是因为\0 的ASCLL值为00为假循环终止。
这样写的好处是既可以赋值赋完的值还可以用来判断。
还有一个问题我们使用strcpy函数主要是为了将源头内容拷贝到目标空间中因此我们不希望源头被改动因此可以使用const修饰一下源头
void my_strcpy(char* ch2, const char* ch1)
这样的话我们就不能够在my_strcpy函数中修改ch1中的内容了 使得程序更加稳定。
关于指针我们最担心的是什么我们会担心它是不是空指针因此可以在解引用之前使用assert断言一下。 assert(ch2 ch1 );//只要有一个是空指针就会报错
注意assert使用需要添加头文件assert.h
最终版本
#include stdio.h
#include string.h
#include assert.h
void my_strcpy(char* ch2, const char* ch1)
{assert(ch2 ch1 );//只要有一个是空指针就会报错while (*ch2 *ch1 ){;}
}
int main()
{char ch1[] hello;char ch2[20];char* ret my_strcpy(ch2,ch1);printf(%s\n, ret);return 0;
}
1.2 strncpy的使用
这个函数和strcpy是不是很相似它们不仅名字相似用法也及其相似 他们之间就相差了一个变量strncpy比strcpy多了一个变量num那么num这个变量的作用是什么呢 num的作用
其实它们之间唯一的区别就是strncpy是长度受限制的字符串函数而strcpy是长度不受限制的字符串函数也就是说你源头字符串长度不论多少都会全部给你 拷贝到目标空间中而strncpy则会通过num的值来拷贝源头字符串长度到目标空间。
//我们要拷贝arr1中的前五个元素
char arr1[] hello world;
char arr2[30] { 0 };
strncpy(arr2,arr1,5);
printf(%s , arr2); 最终打印出来的便是我们想要的前五个字符。
有没有觉得strncpy函数比strcpy函数要灵活一些使用strncpy函数我们可以根据自己的需求来决定拷贝多少字符但是使用strcpy函数却只能拷贝全部的字符。
strncpy加上了一个长度的限制使得拷贝变的更加灵活。 char arr1[] he;
char arr2[30] xxxxxxxxx;
strncpy(arr2,arr1,5);
printf(%s , arr2); 如果我们源头字符串不足所要拷贝的长度会怎样呢 从上图中我们可以看到如果不满足条件后面会自动补充上\0。 2、strcat与strncat
2.1 strcat的使用与模拟
2.1.1 strcat的使用 strcat的作用是实现字符串的链接 那么什么是字符串的链接呢 比如说有一个字符数组arr内容是hello,想要在后面追加world这时候就需要使用strcat函数了 char arr[20] hello ;
strcat(arr, world); 这样我们就可以将world链接到arr中打印arr可以看到此时arr的内容变成了 hello world 函数原型
char * strcat ( char * destination, const char * source );
cplusplus中对strcat的解释 这里有两个问题第一个问题是strcat函数的追加是不是从我们字符串遇到的第一个\0开始追加 第二个问题是 上图中的 \0 是原来的函数把 world 字符串中的 \0 追加到arr中的吗
我们来验证一下
char arr[20] hello\0xxxxxxx ;
strcat(arr, world) 上图就可以解决我们的两个问题了strcat函数的追加是从我们字符串遇到的第一个\0开始追加
world 字符串中的 \0 也会追加到arr中 因此我们可以整理一下strcat函数的追加方式 1.找到目标空间中的第一个\0 2.然后从\0的位置开始追加源头字符串 3.源头字符串的内容包括\0都会追加到目标空间。 2.1.2 strcat的模拟实现
学会了strcat函数的使用接下来我们尝试模拟一下
//dest指目标空间也就是arr;src指源头也就是所要追加的字符串首字符的地址
char* my_strcat(char* dest, const char* src)
{char* ret dest;assert(dest src);//1.找目标空间中的\0while (*dest ! \0)dest;//2.拷贝数据while (*dest *src){;}return ret;
}
int main()
{char arr[20] hello ;my_strcat(arr, world);printf(%s , arr);return 0;
}
提出一个问题我们能不能用上面自己模拟的my_strcat来实现自己给自己追加的操作 因此使用上面自己定义的函数来实现自己给自己追加最终会出现死循环问题。
如果我们使用库里面的strcat函数呢 当前程序可以但是呢没法保证所有程序都可以成功运行一般我们不会使用这个函数给自己追加。 一般自己自己追加都使用 strncat 函数
2.2 strncat的使用
strncat函数与strcat函数的用法也是一样的都是实现字符串的链接不过前者会加上链接字符的长度限制。 strncpy用法展示
char arr[30] hello ;
strncat(arr,liangjing,5 );
printf(%s , arr); 如果我们要追加的字符串少于所规定的长度呢
char arr[30] hello\0xxxxxx ;
strncat(arr,lj,5);
printf(%s , arr); 我们可以发现strncat函数不会和strncpy函数一样不满足会给你补\0 strncat函数只会把最多追加到目标空间。
3、strcmp与strncmp
3.1 strcmp的使用与模拟
3.1.1 strcmp的使用 strcmp -- string compare -字符串的比较 strcmp函数的作用是比较两个字符串的大小 对应位置上的字符进行比较按照ASCII值的大小注意比较的不是字符串的长度。 比如说 函数原型 int strcmp ( const char * str1, const char * str2 ); 我们来看一看这个函数的参数 const char * str1是一个字符指针const char * str2 也是一个字符指针该函数将两个指针指向的字符串进行比较比较后在通过返回值来告诉我们谁大谁小 这是什么意思呢如果说str1指向的字符串比str2指向的字符串大则返回一个大于0的数字如果相等返回0如果str1指向的字符串比str2指向的字符串小则返回一个小于0的数字。 char arr1[ ] abcdef ;
char arr2[ ] abc;
int ret strcmp(arr1, arr2);
printf(%d,ret);
我们来看一下返回值大小 返回1也就是说明字符串arr1大于字符串2
我们也可以将这个代码换一种表示或许会更加直观
int main()
{char arr1[ ] abcdef ;char arr2[ ] abc;int ret strcmp(arr1, arr2);if (ret 0)printf(\n);else if (ret 0)printf(\n);elseprintf(\0);return 0;
}
这样使用比较符号可以更加直观。
注意strcmp函数是通过比较两个字符串对应位置ASCII值的大小来判断两个字符串的大小而不是通过字符串长度。
3.1.1 strcmp的模拟实现
学会了使用strcmp我们可以尝试自己来模拟实现该函数
int my_strcmp(const char* str1, const char* str2)
{while (*str1 *str2){if (*str1 \0)return 0;str1;str2;}if (*str1 *str2)return 1;elsereturn -1;
}
int main()
{char arr1[ ] abcdef ;char arr2[ ] abc;int ret my_strcmp(arr1, arr2);if (ret 0)printf(\n);else if (ret 0)printf(\n);elseprintf(\0);return 0;
}
3.2 strncmp的使用 与上类似直接展示用法
#include stdio.h
#include string.h
#include assert.h
int main()
{char arr1[30] abcdef ;char arr2[30] abcmne;int ret strcmp(arr1,arr2,3);if (ret 0)printf(\n);else if (ret 0)printf(\n);elseprintf(\0);return 0;
} 这里的3是指只比较字符串arr1,arr2中前三个字符 结语
本篇文章主要是介绍了strcpy,strcat,strcmp以及与它们极其相似的strncpy,strncat,strncmp函数下篇文章将会结束字符串函数模块。