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

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

目录


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

image.png


清晰、简单明了。


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


函数模型:

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

image.png

image.png

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


注意以下几点:


源字符串必须以'\0'结束。

会将源字符串中的'\0'拷贝到目标空间。

目标空间必须足够大,以确保能存放源字符串。

目标空间必须可变。

举个例子,比如:


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

image.png

image.png


使用时注意以下几点:


源字符串必须以'\0'结束。

目标空间必须有足够的大,能容纳下源字符串的内容。

目标空间必须可修改。

模拟实现:

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

image.png

image.png


标准规定:


       第一个字符串大于第二个字符串,则返回大于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

image.png


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


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

image.png



使用时注意:


拷贝count个字符从源字符串到目标空间。

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

6、strncat

image.pngimage.png



和strcat也是差不多的。


需要注意的是,当strlen(strSource)+1


7、*strstr

image.png


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

image.png


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


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


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


几点描述:


strDelimit定义了用作分隔符的字符集合

第一个参数指定一个字符串,它包含了0个或者多个由strDelimit字符串中一个或者多个分隔符分割的标记。

strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)

strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置

strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。

如果字符串中不存在更多的标记,则返回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

image.png


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


先来说这个函数的用法:

image.png



用法其实很简单:


需要注意的是:


函数memcpy从src的位置开始向后复制num个字节的数据到dest的内存位置。

这个函数在遇到'\0'的时候并不会停下来。

如果src和dest有任何的重叠,复制的结果都是未定义的。

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


将person结构体复制到person_copy里面


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


模拟实现:

image.png



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



10、*memmove

image.png


它和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

image.png

image.png


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


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




目录
相关文章
|
20天前
|
C语言
【c语言】字符串函数的模拟实现(二)
【c语言】字符串函数的模拟实现(二)
12 1
|
21天前
|
存储 机器学习/深度学习 编译器
C语言基础简单教程
C语言基础简单教程
|
22天前
|
IDE 编译器 开发工具
C语言教程:如何进行环境搭建
C语言教程:如何进行环境搭建
|
21天前
|
C语言
【C语言】:10大字符串函数
【C语言】:10大字符串函数
13 1
|
22天前
|
搜索推荐 编译器 C语言
C语言的简单教程
摘要: 了解C语言中的注释,包括//单行和/*多行*/注释,注意不要嵌套。使用快捷键Ctrl + K, Ctrl + C/U处理注释。C语言的关键字如&#39;int&#39;和&#39;return&#39;有特定含义,通常小写且高亮显示。常量是不可变的,分为不同类型。练习涉及识别不同类型的常量,如整型、实型和字符型。使用printf通过占位符输出常量,例如`printf(&quot;%d&quot;, 10)`。作业包括根据占位符输出个性化信息,如学校名字、高考分数和女朋友的详细信息,并掌握在不同情况下使用\n进行换行。
|
1月前
|
编译器 C语言 C++
【C语言基础】:字符函数和字符串函数-2
【C语言基础】:字符函数和字符串函数
|
1月前
|
C语言
【C语言基础】:字符串函数(二)
【C语言基础】:字符串函数(二)
|
1月前
|
C语言
【C语言基础】:字符函数和字符串函数-1
【C语言基础】:字符函数和字符串函数
|
1月前
|
C语言
【C语言】【字符串函数】【超详解】【上】!!!
【C语言】【字符串函数】【超详解】【上】!!!
15 3
|
1月前
|
安全 编译器 C语言
C语言学习记录——字符串相关函数及部分模拟(strcmp、strncmp、strncat、strncpy、strstr、strtok、strerror)
C语言学习记录——字符串相关函数及部分模拟(strcmp、strncmp、strncat、strncpy、strstr、strtok、strerror)
17 1