0基础C语言自学教程——第十节 字符串函数

写在前面:

各位小伙伴还在为C语言的学习而苦恼嘛?

还在为没有知识体系而烦心嘛?

别急。因为~~~~

接下来的时间里,我会持续推出C语言的有关知识内容

都是满满的干货,从零基础开始哦~,循序渐进😀,直至将C中知识基本全部学完🐂。

欢迎关注我♥,订阅专栏 0基础C语言保姆教学

就可以持续读到我的文章啦😀🐕~~~~

本文为第十节——字符串函数(文末附前9章的链接呦👉)

关于字符串是什么,字符串与数组、指针之间的关系,笔者可能到数据结构再讲,也可能就不讲了😄,看笔者心情(开玩笑的啦~~主要是因为这一部分很简单,没有讲解的价值和必要)

我们本节主要来探讨string.h里的字符串函数

目录

1、*strlen

2、*strcpy

3、*strcat

4、*strcmp

5、strncpy

6、strncat

7、*strstr

8、strtok

9、*memcpy

10、*memmove

11、memcmp


*表示我们会进行模拟实现

我们借助MSDN来辅助学习

1、*strlen

 清晰、简单明了。

作用是:获得一个字符串的长度。

函数模型:

size_t strlen( const char *string );

返回类型:size_t,参数类型:const char*

需要注意以下这么几点:

1、字符串已经'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符个数(不包含'\0')。

2、参数指向的字符串必须要以'\0'结束。

3、注意函数的返回值为size_t,是无符号的。(unsigned int)

对于strlen的模拟实现,方法有很多。

我们介绍三种:

第一种:

//计数器方式
size_t my_strlen(const char * str)
{     
    size_t count = 0;
    while(*str) 
    { 
        count++;
         str++;
     }
     return count;
}

 第二种:

//不能创建临时变量计数器
size_t my_strlen(const char * str)
{ 
    if(*str == '\0')
         return 0;
     else
         return 1 + my_strlen(str+1);
}

第三种:

//指针-指针的方式size_t my_strlen(char *s)
{
       char *p = s;
       while(*p != ‘\0’ )
              p++;
       return p-s;
}

 其实这三种方法都易于接收。还是比较简单的。

2、*strcpy

 我想笔者已经不需要再去重复了,应该都能看懂。

注意以下几点:

  1. 源字符串必须以'\0'结束。
  2. 会将源字符串中的'\0'拷贝到目标空间。
  3. 目标空间必须足够大,以确保能存放源字符串。
  4. 目标空间必须可变。

举个例子,比如:

char* strcpy(char* s1, const char*s2);

意思就是把s2拷贝到s1里去。然后返回s1。

以下是一个例子:

 模拟实现:

char *my_strcpy(char *dest, const char*src)
{
   char *ret = dest;
   assert(dest != NULL);
   assert(src != NULL);
   while((*dest++ = *src++))
     {
         ;
     } 
    return ret;
}

3、*strcat

 

 使用时注意以下几点:

  1. 源字符串必须以'\0'结束。
  2. 目标空间必须有足够的大,能容纳下源字符串的内容。
  3. 目标空间必须可修改。

模拟实现:

char* my_strcat(char* dest, const char* src)
{
	char* ret = dest; 
	assert(dest != NULL); 
	assert(src != NULL); 
	while (*dest) 
	{ 
		dest++; 
	} 
	while ((*dest++ = *src++)) 
	{ ; } 
	return ret;
}

4、*strcmp

 

标准规定:

        第一个字符串大于第二个字符串,则返回大于0的数字

        第一个字符串等于第二个字符串,则返回0

        第一个字符串小于第二个字符串,则返回小于0的数字

int my_strcmp(const char* src, const char* dst) 
{ 
	int ret = 0;
	assert(src != NULL);
	assert(dst != NULL);
	while (!(ret = *(unsigned char*)src - *(unsigned char*)dst) && *dst)
	{
		++src;
		++dst;
	}
	if (ret < 0)
		ret = -1;
	else if (ret > 0)
		ret = 1;
	return ret;
}

 很简单,很好理解。

5、strncpy

 我们很容易发现,strcpy和strncpy就有一点不一样。那就是strncpy多了一个参数count。也可以就理解为就是n。也就是说n就是其要拷贝的个数。

其他的,和strcpy一样。如下图:

使用时注意: 

  1. 拷贝count个字符从源字符串到目标空间。
  2. 如果源字符串的长度小于count,则拷贝完源字符串之后,在目标的后边追加0,直到count个。

6、strncat

 

 和strcat也是差不多的。

需要注意的是,当strlen(strSource)+1<n,那么拷贝多少就算多少。

7、*strstr

 

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);
	}
}

 还是很简单的。

8、strtok

这个函数它没有那么单纯。

它 的目的主要是用来切割字符串的。

而切割的标准就是依照参数 strDelimit

几点描述:

  1. strDelimit定义了用作分隔符的字符集合
  2. 第一个参数指定一个字符串,它包含了0个或者多个由strDelimit字符串中一个或者多个分隔符分割的标记。
  3. strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  4. strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置
  5. strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  6. 如果字符串中不存在更多的标记,则返回NULL指针。

什么意思具体来说?

我们通过一个例子来 说明

 在字符串 “,.- This, a sample string.”里,它会找到下一个 strDelimit中的字符。

第一个是“, 。- ”,第二个是“,”,那么其会标记上一个strDelimit中的后一个字符,即T,然后将","换成"\0",所以,运行完 pch = strtok (str," ,.-"); pch指向的是T,字符串为“,.- This\0 a sample string.”(后面的空格并不会去修改)

然后,进入while循环。strtok的第一个参数是NULL,那么其会从上一个标记处(就是上一次的分隔符号的位置)开始寻找,然后去找strDelimit里的分隔符号。直到找到,将其变为\0。

如果第一个参数为NULL并且找不到分隔符号的时候,就会返回空指针。

9、*memcpy

 一般情况下,src都是0,如果不是0,用的如果 不恰当会引起“麻烦”,我们以后再说。

先来说这个函数的用法:

用法其实很简单:

需要注意的是: 

  1.  函数memcpy从src的位置开始向后复制num个字节的数据到dest的内存位置。
  2. 这个函数在遇到'\0'的时候并不会停下来。
  3. 如果src和dest有任何的重叠,复制的结果都是未定义的。

 

 如图,将myname复制到person.name里面

将person结构体复制到person_copy里面

后面第三个元素表示的是复制的字节数。

模拟实现:

 注意,如果是结构体类型这种方法应该是不可以的。在这里我们只做简单的模拟实现。到了C++中我们会用类来去实现。

 

10、*memmove

它和memcpy的区别就是, memcpy的src和dest不可以有空间上的重叠。

但是memmove是可以有的。

我们在模拟实现的时候只需要加上一个条件就可以了。

void* memmove(void* dst, const void* src, size_t count) 
{
	void* ret = dst; 
	if (dst <= src || (char*)dst >= ((char*)src + count)) 
	{ 
		while (count--) 
		{ *(char*)dst = *(char*)src; 
		dst = (char*)dst + 1;
		src = (char*)src + 1; 
		} 
	} 
	else 
	{ //需要从高地址往低地址拷贝
		dst = (char*)dst + count - 1; 
		src = (char*)src + count - 1; 
		while (count--) 
		{ 
		    *(char*)dst = *(char*)src; 
		    dst = (char*)dst - 1; 
		    src = (char*)src - 1; 
		} 
	}
	return(ret);
}

11、memcmp

 

 这个很简单,类比于strcmp,主要是在后面有一个参数,它会从第count的位置开始比较。

strerror等略(不属于string.h里,本节不讲)

行了行了,下班了。。。。。

欢迎各位看官关注我@jxwd,订阅专栏,就能持续看到我的文章啦😀😀

0基础C语言自学教程——第九节 从底层汇编的角度简单理解函数栈帧的创建和销毁_jxwd的博客-CSDN博客

0基础C语言自学教程——第八节 函数指针数组的各种关系_jxwd的博客-CSDN博客

0基础C语言自学教程——第七节 初始指针_jxwd的博客-CSDN博客

0基础C语言保姆教程——第六节 操作符、表达式和语句_jxwd的博客-CSDN博客

0基础C语言保姆教学——第五节 数组_jxwd的博客-CSDN博客

0基础C语言保姆教程——第4节 函数_jxwd的博客-CSDN博客

0基础C语言自学教程——第三节 分支与循环_jxwd的博客-CSDN博客

0基础C保姆自学 第二节——初步认识C语言的全部知识框架_jxwd的博客-CSDN博客_c语言全部框架

C语言自学保姆教程——第一节--编译准备与第一个C程序_jxwd的博客-CSDN博客

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jxwd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值