C语言string库之常用字符和字符串函数详解

简介: C语言string库之常用字符和字符串函数详解

一、主要作用介绍

1、求字符串长度

2、长度不受限制的字符串函数

       strcpy->将源地址到结束符 \0 的字符都复制到目标地址中

       strcat->将源字符串的副本追加到目标字符串后面

       strcmp->比较两个字符串 第一个字符串大于第二个字符串,则返回大于0的数字,第一个字符串等于第二个字符串,则返回0,第一个字符串小于第二个字符串,则返回小于0的数字

3、长度受限制的字符串函数介绍

       strncpy->拷贝 num 个字符从源字符串到目标空间

       strncat->将源字符串中指定的字符数量追加到目标字符串后面

       strncmp->比较两个字符串,但此处指定了第二个字符串比较的数量,比较的规则同上strcmp

4、字符串查找

       strstr->查找子字符串

       strtok->将字符串拆分为标记

     

5、错误信息报告

       strerror->返回错误码,所对应的错误信息。

6、字符操作

     内存操作函数

       memcpy->从源地址 的位置开始向后复制 num 个字节的数据到目标地址 的内存位置。

       memmove->和memcpy作用效果相同,但是和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的

       memset->填充内存块

       memcmp->比较从ptr1和ptr2指针开始的num个字节

二、函数详解

1、strlen

原型:size_t strlen ( const char * str );

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

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

       注意函数的返回值为size_t ,是无符号的( 易错 )  


2、strcp

y

原型:char* strcpy(char * destination, const char * source );

       将source指向的C字符串复制到destination指向的数组中,包括终止空字符(并在该点停止)。

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

       会将源字符串中的 '\0' 拷贝到目标空间,并且他会返回将 destination指向的数组的地址。

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

       目标空间必须可变。


 

3、 strcat

原型:char * strcat ( char * destination, const char * source );

将源字符串的副本追加到目标字符串。结束的空字符 destination被source的第一个字符覆盖,并包含一个空字符 在由两者在destination中串联而成的新字符串的末尾。并且返回destination的地址。

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

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

       目标空间必须可修改。

4、strcmp

原型:int strcmp ( const char * str1, const char * str2 );

      这个函数开始比较每个字符串的第一个字符。如果它们是相等的 否则,它继续使用以下对,直到字符不同或直到结束 达到空字符。

       标准规定:

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

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

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

5、strncpy

原型:char * strncpy ( char * destination, const char * source, size_t num );

将源的第一个num字符复制到目标。如果源C字符串的结束 (由空字符表示)在复制num个字符之前找到, 目标将用零填充,直到向其写入总数为num个字符为止。 并且他会返回将 destination指向的数组的地址。

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

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

6、strncat

原型:char * strncat ( char * destination, const char * source, size_t num );

将源的从第一个数的num字符附加到目标,加上一个结束的空字符。返回destination指向的数组的地址。

        如果source中的C字符串的长度小于num,则只包含直到结束的内容复制空字符。

7、strncmp

原型:int strncmp ( const char * str1, const char * str2, size_t num );

比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

       

8、strstr

原型:char * strstr ( const char *str1, const char * str2);

返回指向 str2 中第一次出现的 str1 的指针,如果 str2 不是str1 的一部分,则返回一个空指针。

       匹配过程不包括终止空字符,但它到此为止。

 

9、strstok

原型:char * strtok ( char * str, const char * sep );

sep参数是个字符串,定义了用作分隔符的字符集合

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

     

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

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

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

       如果字符串中不存在更多的标记,则返回 NULL 指针。

10、 strerror

原型:char * strerror ( int errnum );

 解释 errnum 的值,生成一个字符串,其中包含描述错误条件的消息,就像由库的函数设置为 errno 一样。 返回的指针指向静态分配的字符串,程序不应修改该字符串。对此函数的进一步调用可能会覆盖其内容(不需要特定的库实现来避免数据争用)。 strerror 生成的错误字符串可能特定于每个系统和库实现。

11、 memcpy

原型:void * memcpy ( void * destination, const void * source, size_t num );

       函数memcpysource位置开始向后复制 num 个字节的数据到 destination 的内存位置。

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

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

12、memove

原型:void * memmove ( void * destination, const void * source, size_t num );

   和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。

       如果源空间和目标空间出现重叠,就得使用memmove函数处理。

13、 memcmp

原型:int memcmp ( const void * ptr1, const void * ptr2, size_t num );

  比较从ptr1ptr2指针开始的num个字节

       返回值如下:

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

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

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


三、其中最常用函数的模拟实现

1、 strlen

int my_len(const char* s)
{
  int re = 0;
  while (*s)
  {
    re++;
    s++;
  }
  return re;
}

2、strcpy

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

3、strcat

char* my_strcat(char* s1, char* s2)
{
  assert(s1);
  assert(s2);
  char* re = s1;
  while (*s1)
  {
    s1++;
  }
  while (*s2)
  {
    *s1 = *s2;
    s1++;
    s2++;
  }
  *s1 = '\0';
  return re;
}

4、strstr

char* my_strstr(const char* s1, const char* s2)
{
  char *q1, *q2;
  char* cp = (char*)s1;
  if (!*s2)
    return (char*)s1;
  while (*cp)
  {
    q1 = cp;
    q2 = (char*)s2;
    while (*q1&&*q2&&!(*q1-*q2))
    {
      q1++;
      q2++;
    }
    if (!*q2)
      return cp;
    cp++;
  }
  return NULL;
}

5、strcmp

int my_strcmp(const char* s1, const char* s2)
{
  while (*s1 || *s2)
  {
    if (*s1 > *s2)
      return 0;
    else if (*s1 == *s2)
    {
      s1++;
      s2++;
    }
    else
      return -1;
  }
  return 1;
}

6、memcpy

void* my_memcpy(void* st1, const void* st2,size_t num)
{
  assert(st1 != NULL);
  assert(st2 != NULL);
  void* re = st1;
  while (num--)
  {
    *(char *)st1 = *(char *)st2;
    st1 = (char*)st1 + 1;
    st2 = (char*)st2 + 1;
  }
  return re;
}

7、memmove

void* my_memmove(void* s1, void* s2, size_t num)
{
  void* re = s1;
  if (s1 <= s2 || (char*)s1 >= ((char*)s2 + num))
  {
    while (num--) {
      *(char*)s1 = *(char*)s2;
      s1 = (char*)s1 + 1;
      s2 = (char*)s2 + 1;
    }
  }
  else
  {
    s1 = (char*)s1 + num - 1;
    s2 = (char*)s2 + num - 1;
    while (num--) {
      *(char*)s1 = *(char*)s2;
      s1 = (char*)s1 - 1;
      s2 = (char*)s2 - 1;
    }
  }
  return re;
}

7、memmove

void* my_memmove(void* s1, void* s2, size_t num)
{
  void* re = s1;
  if (s1 <= s2 || (char*)s1 >= ((char*)s2 + num))
  {
    while (num--) {
      *(char*)s1 = *(char*)s2;
      s1 = (char*)s1 + 1;
      s2 = (char*)s2 + 1;
    }
  }
  else
  {
    s1 = (char*)s1 + num - 1;
    s2 = (char*)s2 + num - 1;
    while (num--) {
      *(char*)s1 = *(char*)s2;
      s1 = (char*)s1 - 1;
      s2 = (char*)s2 - 1;
    }
  }
  return re;
}

相关文章
|
1天前
|
C语言
【C语言基础】:字符串函数(二)
【C语言基础】:字符串函数(二)
|
1天前
|
编译器 C语言 C++
【C语言基础】:字符函数和字符串函数-2
【C语言基础】:字符函数和字符串函数
|
1天前
|
C语言
【C语言基础】:字符函数和字符串函数-1
【C语言基础】:字符函数和字符串函数
|
9天前
|
C语言
C语言学习记录——鹏哥字符分类函数、字符转换函数
C语言学习记录——鹏哥字符分类函数、字符转换函数
10 2
|
9天前
|
安全 编译器 C语言
C语言学习记录——字符串相关函数及部分模拟(strcmp、strncmp、strncat、strncpy、strstr、strtok、strerror)
C语言学习记录——字符串相关函数及部分模拟(strcmp、strncmp、strncat、strncpy、strstr、strtok、strerror)
12 1
|
9天前
|
C语言
C语言学习记录——模拟字符串相关函数(strcpy、strlen、strcat)相关知识-const、typedef
C语言学习记录——模拟字符串相关函数(strcpy、strlen、strcat)相关知识-const、typedef
9 1
|
9天前
|
C语言
C语言小插曲——对图形库的初步探索(消除小球小游戏)
C语言小插曲——对图形库的初步探索(消除小球小游戏)
8 0
|
10天前
|
C语言
【C语言】【字符串函数】【超详解】【下】!!!
【C语言】【字符串函数】【超详解】【下】!!!
|
2天前
Failed to bind properties under ‘logging.level‘ to java.util.Map java.lang.String, java.lang.String
Failed to bind properties under ‘logging.level‘ to java.util.Map java.lang.String, java.lang.String
4 0
|
3天前
|
安全 Java 数据安全/隐私保护
Java基础4-一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!(二)
Java基础4-一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!(二)
12 0