欢迎来到白刘的领域 Miracle_86.-CSDN博客
系列专栏 C语言知识
先赞后看,已成习惯
创作不易,多多支持!

目录
七、strncpy的使用以及模拟实现
八、strncat的使用以及模拟实现
九、strncmp的使用以及模拟实现
十、strstr的使用以及模拟实现
十一、strtok的使用
十二、strerror的使用
七、strncpy的使用以及模拟实现
char* strncpy(char* destination, const char* source, size_t num); 
在上篇中,我们学到了strcpy,知道了它是用来拷贝字符串的:
C语言字符函数与字符串函数:编织文字的舞会之梦(上)-CSDN博客
这个strncpy,它相比较strcpy多了个字母n,我们再来看上面的函数原型,多了个size_t类型的num,这个n是代表num个字符。也就是说这个函数可以指定拷贝几个字符。
1.原理:将源的前 num 个字符复制到目标。如果源 C 字符串的末尾(由 null 字符表示)在复制 num 字符之前找到,destination 用零填充,直到写入总共 num 个字符。
2.拷贝num个字符从源字符串到目标空间
3.如果源字符串的长度小于num,则拷贝完源字符串后,在目标的后面追加0,直到num个。
来看它的使用:
#include <stdio.h>
#include <string.h>
int main()
{
	char src[40];
	char dest[40];
	strncpy(src, "Hello World",12);
	strncpy(dest, src,15);
	printf("最终的目标字符串:%s\n", dest);
	return 0;
} 
这里编译器给出警告,也就是我们说的追加0:

strncpy的模拟实现,根据原理其实很好操作:
char* mystrncpy(char* dst, const char* src, size_t n)
{
    int i;
    for (i = 0; src[i] && i < n; i++)
    {
        dst[i] = src[i];
    }
    if (i < n)
    {
        dst[i] = 0;
    }
    return dst;
} 
八、strncat的使用以及模拟实现
char* strncat(char* destination, const char* source, size_t num); 
同理,仿照strncpy,这个应该是追加num个字符到目标空间。
1.将source指向字符串的前num个字符追加到destination指向的字符串末尾,再追加⼀个 \0 字符。
2.如果source 指向的字符串的⻓度⼩于num的时候,只会将字符串中到 \0 的内容追加到destination指向的字符串末尾。
直接上代码:
/* strncat example */
#include <stdio.h>
#include <string.h>
int main()
{
	char str1[20];
	char str2[20];
	strcpy(str1, "To be ");
	strcpy(str2, "or not to be");
	strncat(str1, str2, 6);
	printf("%s\n", str1);
	return 0;
} 
再来看模拟实现:
char * mystrncat(char * dst, const char * src, size_t n)
{
	char * tmp = dst;
   
  while (*dst)
  {
    dst++;
  }
   
  int i;
  for (i = 0; src[i] && i < n; i++)
  {
    dst[i] = src[i];
  }
   
  dst[i] = 0;
  return tmp;
} 
九、strncmp的使用以及模拟实现
int strncmp(const char* str1, const char* str2, size_t num);
 
⽐较str1和str2的前num个字符,如果相等就继续往后⽐较,最多⽐较num个字⺟,如果提前发现不⼀样,就提前结束,⼤的字符所在的字符串⼤于另外⼀个。如果num个字符都相等,就是相等返回0。

我们来看模拟实现:
int Mystrncmp(const char* str1, const char* str2, int n)
{
	assert(str1 != NULL && str2 != NULL);
	while (n-- && *str1 == *str2)
	{
		str1++;
		str2++;
	}
	return *str1 - *str2;
} 
将n放进循环中再自减,达到比较n个字符这一效果。
十、strstr的使用以及模拟实现
这个其实不太好想是什么意思,单从字面上来讲,放了两个str是什么意思呢?我们来看函数原型:
char* strstr(const char* str1, const char* str2);
 
其实这个函数是用来返回字符串str2在字符串str1中第一次出现的位置。
细节注意:字符串的比较的不包含字符'\0',以'\0'作为结束标准。
#include <stdio.h>
#include <string.h>
int main()
{
	char str[] = "This is a simple string";
	char* pch;
	pch = strstr(str, "simple");
	strncpy(pch, "sample", 6);
	printf("%s\n", str);
	return 0;
} 
运行结果:

模拟实现:
思路:首先str2可以是'\0',如果是的话,直接返回str1的地址。接下来我们创建一个指针cp来指向str1,然后将其放进循环,我们还需要两个指针分别指向两个字符串,然后遍历一一对照是否相等。
char* strstr(const char* str1, const char* str2)
{
	char* cp = (char*)str1;
	char* s1, * s2;
	if (!*str2)
		return((char*)str1);
	while (*cp)
	{
		s1 = cp;
		s2 = (char*)str2;
		while (*s1 && *s2 && !(*s1 - *s2))
			s1++, s2++;
		if (!*s2)
			return(cp);
		cp++;
	}
	return(NULL);
} 
十一、strtok的使用
char* strtok(char* str, const char* sep); 
这个函数是用来分割字符串的。
1.sep参数指向⼀个字符串,定义了⽤作分隔符的字符集合。
2.第⼀个参数指定⼀个字符串,它包含了0个或者多个由sep字符串中⼀个或者多个分隔符分割的标记。
3.strtok函数找到str中的下⼀个标记,并将其⽤ \0 结尾,返回⼀个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使⽤strtok函数切分的字符串⼀般都是临时拷⻉的内容并且可修改。)
4.strtok函数的第⼀个参数不为 比特就业课主页:https://m.cctalk.com/inst/s9yewhfr
NULL ,函数将找到str中第⼀个标记,strtok函数将保存它在字符串中的位置。5.strtok函数的第⼀个参数为 NULL ,函数将在同⼀个字符串中被保存的位置开始,查找下⼀个标记。
6.如果字符串中不存在更多的标记,则返回 NULL 指针。
#include <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "192.168.6.111";
	char* sep = ".";
	char* str = NULL;
	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
	{
		printf("%s\n", str);
	}
	return 0;
} 
其实就记住,str是要分割的字符串,sep是字符的集合,str里面有sep里的元素,然后这个函数会找到str中要分割的那个点(也就是sep的元素),并且将其替换成'\0',返回值为首元素地址,同时也会记录'\0'之后的首元素地址。
十二、strerror的使用
char* strerror(int errnum); 
error这个单词大家都知道,是错误的意思,那这个函数就是用来返回错误的。
strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来。在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在< errno.h> 这个头⽂件中说明的,C语⾔程序启动的时候就会使⽤⼀个全⾯的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表⽰没有错误,当我们在使⽤标准库中的函数的时候发⽣了某种错误,就会讲对应的错误码,存放在errno中,⽽⼀个错误码的数字是整数很难理解是什么意思,所以每⼀个错误码都是有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。
#include <errno.h>
#include <string.h>
#include <stdio.h>
//我们打印⼀下0~10这些错误码对应的信息
int main()
{
	int i = 0;
	for (i = 0; i <= 10; i++) {
		printf("%s\n", strerror(i));
	}
	return 0;
} 
在Window11+VS2022环境下输出结果如下:

再来举个栗子:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	FILE* pFile;
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
		printf("Error opening file unexist.ent: %s\n", strerror(errno));
	return 0;
} 
输出结果:
Error opening file unexist.ent: No such file or directory 
也可以了解一下 perror函数,
perror 函数相当于⼀次将上述代码中的第9⾏完成了,直接将错误信息打印出来。perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
	FILE* pFile;
	pFile = fopen("unexist.ent", "r");
	if (pFile == NULL)
		perror("Error opening file unexist.ent");
	return 0;
} 
输出结果是一样的:
Error opening file unexist.ent: No such file or directory 
完












![[Java基础揉碎]final关键字](https://img-blog.csdnimg.cn/direct/8727d75b8df745cda248eef23ec0ae0a.png)
![[AIGC] SQL中的数据添加和操作:数据类型介绍](https://img-blog.csdnimg.cn/direct/e399561dbfb0408893f353f1a41d68a4.png)





