你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)

我们知道包含string.h头文件后,就可以使用strncpy,strncmp,strncat,strstr,strtok这些库函数,接下来让我们了解他们。

目录

        #strncpy

        #strncmp

        #strncat

        #strstr

        #strtok

        #下期预告


#strncpy

该库函数作用和strcpy很相似,不同点在于

发现了吗,strncpy多了一个size_t num,这是要拷贝的字符数目,而strcpy是全拷贝。 

废话不多说,来看代码

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 

int main()
{

	char str1[30] = "XXXXXXXXXXXXXX";
	char str2[20] = "hahaha";
	strncpy(str1, str2, 7);


	return 0;
}

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第1张图片

如果说num小于str2的长度,正常复制

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 

int main()
{

	char str1[30] = "XXXX";
	char str2[20] = "hahaha";
	strncpy(str1, str2, 5);

	return 0;
}

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第2张图片

因为初始化时,剩下的空间都初始化了,如果石str1未初始化,就会是这样:

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第3张图片

str2末尾没有\0,还需要自己再加,如果全部复制,不初始化str1也ok,但最好初始化

如果要复制的长度大于str2,也就是源字符串,那么多出来的部分拷贝\0

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 

int main()
{

	char str1[30] = "XXXXXXXXXXXXXXXXXXX";
	char str2[20] = "hahaha";
	strncpy(str1, str2, 10);

	return 0;
}

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第4张图片

补充一点,二者copy时遇到\0都会停下来,strncpy遇到后超过部分还补\0

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第5张图片

 

#strncmp

 这个和上面类似,比较num个字符,直到这n个字符都比完,比较方式同strcmp函数

#strncat

同样的道理,向str1的末尾追加num个以str2为首地址开始的字符 ,但是有一些和strncpy不同的区别,看图:

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第6张图片

这个很正常,都可以理解,接下来看好了:

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第7张图片

哈?我明明只追加6个字符,没追加最后的\0啊?

是的 ,strncat不管追加多少字符,都会在追加的最后自己加上\0,那么这样呢?

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第8张图片

即使超过源字符串长度,他不会像strncpy那样补\0,他只追加一个\0 

#strstr

该库函数作用是在一个字符串中找另一个字符串,并返回那个找到的字符串的首位置,若没有找到,返回NULL。

接下来我们模拟实现他

(这里最好的算法是KMP算法,在数据结构里会讲到,这里没有用到)

#define _CRT_SECURE_NO_WARNINGS 1
#include 

const char* my_strstr(const char* str_orign, const char* str_find)
{
	const char* orign = str_orign;
	const char* p1 = orign;
	const char* p2 = str_find;

	while (*orign)
	{
	
		p1 = orign;
		p2 = str_find;

		while (*p1 && *p2 && (*p1 == *p2))
		{
			p1++;
			p2++;
		}
		if (*p2 == '\0')
			return orign;

		orign++;
	}

	return NULL;
}

//模拟实现strstr
int main()
{

	char str_orign[30] = "da wu wo x ni wo......";
	char str_find[20] = "woo";
	const char* p = my_strstr(str_orign, str_find);

	if (p != NULL)
		printf("%s", p);
	else
		printf("Can not find it\n");
	return 0;
}

#strtok

这是个用来分割字符串的函数,sep是存放分隔符的,没有先后顺序之分,str则是我们要分割的字符串,看代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 

int main()
{

	char str[30] = "haha.hehe#hiahia*";
	char sep[10] = ".#*";

	printf("%s", strtok(str, sep));

	return 0;
}

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第9张图片

 咦,奶奶个腿滴,感觉咋不对劲呢,为什么没有全部分割呢?

接下来讲讲这个函数的原理:

strtok函数会找到str中的下一个标记,并将其末尾用\0结尾,也就是将分隔符换成\0,返回一个指向这个标记的指针,也就是说,我们第一次使用strtok时,返回的标记指向haha的h,然后我们打印时遇到\0停止:

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第10张图片

所以我们打印出来haha,那么如何分割剩下的字符串呢?

 接下来看代码,这么用:

#include 
#include 

int main()
{

	char str[30] = "haha.hehe#hiahia*";
	char sep[10] = ".#*";

    char* temp;
    for (temp = strtok(str, sep); temp != NULL; 
                      temp = strtok(NULL, sep))
    {
	    printf("%s\n", temp);
    }

	return 0;
}

接下来传的就是NULL空指针,函数将从我们第一次使用后保存的位置开始查找下一个标记,找到后将其末尾分隔符换成\0,返回标记,看这次我们的打印结果:

你应该知道的C语言干货(4)(strncpy,strncmp,strncat,strstr,strtok)_第11张图片

分隔成功~  

#下期预告

内存函数:

memset

memcpy

memmove

memcmp

你可能感兴趣的:(C语言,c语言)