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

相关文章
|
23天前
|
存储 C语言
【C语言基础考研向】10 字符数组初始化及传递和scanf 读取字符串
本文介绍了C语言中字符数组的初始化方法及其在函数间传递的注意事项。字符数组初始化有两种方式:逐个字符赋值或整体初始化字符串。实际工作中常用后者,如`char c[10]=&quot;hello&quot;`。示例代码展示了如何初始化及传递字符数组,并解释了为何未正确添加结束符`\0`会导致乱码。此外,还讨论了`scanf`函数读取字符串时忽略空格和回车的特点。
|
26天前
|
存储 人工智能 C语言
C语言程序设计核心详解 第六章 数组_一维数组_二维数组_字符数组详解
本章介绍了C语言中的数组概念及应用。数组是一种存储同一类型数据的线性结构,通过下标访问元素。一维数组定义需指定长度,如`int a[10]`,并遵循命名规则。数组元素初始化可使用 `{}`,多余初值补0,少则随机。二维数组扩展了维度,定义形式为`int a[3][4]`,按行优先顺序存储。字符数组用于存储字符串,初始化时需添加结束符`\0`。此外,介绍了字符串处理函数,如`strcat()`、`strcpy()`、`strcmp()` 和 `strlen()`,用于拼接、复制、比较和计算字符串长度。
|
2月前
|
安全 程序员 C语言
【C语言】字符串函数及其模拟实现
【C语言】字符串函数及其模拟实现
|
2月前
|
编译器 C语言
【C语言小知识】ctype.h系列的字符函数
【C语言小知识】ctype.h系列的字符函数
|
2月前
|
存储 Java 编译器
String能存储多少个字符
String能存储多少个字符
|
2月前
|
存储 C++
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
【C/C++学习笔记】string 类型的输入操作符和 getline 函数分别如何处理空白字符
32 0
|
2月前
|
C语言
【C语言篇】字符和字符串以及内存函数详细介绍与模拟实现(下篇)
perror函数打印完参数部分的字符串后,再打印⼀个冒号和⼀个空格,再打印错误信息。
|
2月前
|
存储 安全 编译器
【C语言篇】字符和字符串以及内存函数的详细介绍与模拟实现(上篇)
当然可以用scanf和printf输入输出,这里在之前【C语言篇】scanf和printf万字超详细介绍(基本加拓展用法)已经讲过了,这里就不再赘述,主要介绍只针对字符的函数.
|
11天前
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
24 0
java基础(13)String类
|
2月前
|
API 索引
String类下常用API
String类下常用API
38 1