常用的字符函数和字符串函数

简介: 常用的字符函数和字符串函数

文章目录

一、分类

  • 求字符长度:strlen
  • 长度不受限制的字符串函数:strcpy 、strcat 、strcmp
  • 长度受限制的字符串函数:strncpy 、strncat 、strncmp
  • 字符串查找:strstr、strtok
  • 错误信息报告:strerror
  • 字符操作
  • 内存操作函数:memcpy、memmove、memset、memcmp

二、函数实现过程

1.strlen

作用:strlen 计算字符串 str 的长度,直到空结束字符,但不包括空结束字符。

头文件

声明:

size_t strlen(const char *str)

注意

  • 字符串以‘\0’作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包 含 ‘\0’ )。
  • 参数指向的字符串必须要以 ‘\0’ 结束。
  • 注意函数的返回值为size_t,是无符号的。

模拟实现

  • 计数器
size_t My_strlen(const char* str)
{
  assert(str != NULL);
  int 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(const char* str)
{
  const char* star = str;
  const char* end = str;
  while (*end != '\0')
  {
    end++;
  }
  return end - star;
}

2、strcpy和strncpy

作用:strcpy:把 src 所指向的字符串复制到 dest。

strncpy: 把 src 所指向的字符串复制到 dest,最多复制 n 个字符。

头文件

声明

char* strcpy(char * destination, const char * source );

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

注意

  • 源字符串必须以 ‘\0’ 结束。
  • 会将源字符串中的 ‘\0’ 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变。
  • strncpy
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

模拟实现

strcpy

char* My_strcpy(char* dest, const char* src)
{
  assert(dest != NULL && src != NULL);
   char* res = dest;
  while ( *res==*src )
  {
    *res++;
    *src++
  }
  return res;
}

strncpy

char * My_strncpy(char * dest, const char *src, size_t num)
{
    assert(dest);
    assert(src);
    char *ret = dest;
    while (num--)
    {
        *dest++ = *src++;
    }
    return ret;
}

3、strcat和strncat

作用

strcat:把 src 所指向的字符串追加到 dest 所指向的字符串的结尾。

strncat:把 src 所指向的字符串追加到 dest 所指向的字符串的结尾,直到 n 字符长度为止。

头文件

声明

char *strcat(char *dest, const char *src)

char *strncat(char *dest, const char *src, size_t n)

注意

  • dest – 指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
  • src – 指向要追加的字符串,该字符串不会覆盖目标字符串。
  • 源字符串必须以 ‘\0’ 结束。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。
  • 模拟实现
    strcat
char* My_strcat(char* dest, const char* src)
{
  assert(dest != NULL && src != NULL);
  while (*dest != '\0')
  {
    dest++;
  }
  while (*dest = *src)
  {
    dest++;
    src++;
  }
  return dest;
}

strncat

char* My_strncat(char* dest, char* src, size_t n)
{
  char* ret = dest;
  assert(dest && src);
  while (*dest != '\0')
  {
    dest++;
  }
  while (count && (*des++ = *src++))
  {
    n--;
  }
  *dest = '\0';
  return ret;
  }

4、 strcmp和strncmp

作用

strcmp:把 str1 所指向的字符串和 str2 所指向的字符串进行比较.

strncmp:把 str1 和 str2 进行比较,最多比较前 n 个字节。

头文件

声明

int strcmp(const char *str1, const char *str2)

int strncmp(const char *str1, const char *str2, size_t n)

注意

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

模拟实现

strcmp

int My_strcmp(const char* str1, const char* str2)
{
  assert(str1 && str2);
  while (*str1 == *str2)
  {
    if (*str1 == '\0')
    {
      return 0;
    }
    str1++;
    str2++;
  }
  return *str2 - *str1;
}

strncmp

int my_strncmp(const char *str1, const char *str2, size_t n)
{
  assert(str1);
  assert(str2);
  while (*str1&&*str2&&(*str1 == *str2)&&n--)
  {
    str1++;
    str2++;
  }
  return *str1 - *str2;
}

5、strstr

作用

在字符串 haystack 中查找第一次出现字符串 needle 的位置,不包含终止符 ‘\0’,如果未找到则返回 null。

声明

char *strstr(const char *haystack, const char *needle)

头文件

模拟实现

char* My_strstr(const char* string, const char* strCharSet)
{
  assert(string&&strCharSet);
  const char* dest =NULL;
  const char* src =strCharSet;
  const char* cp = string;
  if (*strCharSet == '\0')
  {
    return (char*)string;
  }
  while (*cp)
  {
    dest = cp;
    src = strCharSet;
    while ((*dest == *src) && *dest != '\0' && *src != '\0')
    {
      dest++;
      src++;
    }
    if (*src == '\0')
    {
      return (char*)cp;
    }
    else
    {
      cp++;
    }
  }
  return NULL;
}

6、strtok

作用

分解字符串 str 为一组字符串,delim 为分隔符

头文件

声明

char *strtok(char *str, const char *delim)

参数

  • str – 要被分解成一组小字符串的字符串。
  • delim – 包含分隔符的 C 字符串。
  • 返回值
  • 该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。


注意

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

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

7、strerror

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

char * strerror ( int errnum );

字符分类函数:

iscntrl 任何控制字符

isspace 空白字符:空格‘ ’,换页‘\f’,换行’\n’,回车‘\r’,制表符’\t’或者垂直制表符’\v’

isdigit 十进制数字 0~9

isxdigit 十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A-F

islower 小写字母a~z

isupper 大写字母A~Z

isalpha 字母a~z或A-Z

isalnum 字母或者数字,a~z,A-Z,0-9

ispunct 标点符号,任何不属于数字或者字母的图形字符(可打印)

isgraph 任何图形字符

isprint 任何可打印字符,包括图形字符和空白字符

二、内存函数

1、memset

作用

复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。

头文件

声明

void *memset(void *str, int c, size_t n)

参数

  • str – 指向要填充的内存块。
  • c – 要被设置的值。该值以 int 形式传递,但是函数在填充内存块时是使用该值的无符号字符形式。
  • n – 要被设置为该值的字符数。
  • 返回值
  • 该值返回一个指向存储区 str 的指针。
  • 实现

806ba9a1da8919c44729b90c3124afa.png

2、memcmp

作用

存储区 str1 和存储区 str2 的前 n 个字节进行比较。

头文件

声明

int memcmp(const void *str1, const void *str2, size_t n)

参数

  • str1 – 指向内存块的指针。
  • str2 – 指向内存块的指针。
  • n – 要被比较的字节数。
  • 返回值
  • 如果返回值 < 0,则表示 str1 小于 str2。
  • 如果返回值 > 0,则表示 str1 大于 str2。
  • 如果返回值 = 0,则表示 str1 等于 str2。
  • 注意
  • memcmp函数作用与strcmp作用相同,而strcmp只适用于字符串。

**3、memcpy与memmove

作用

两者作用都是从 str2 复制 n 个字符到 str1。

头文件

声明

void *memcmp(void *str1, const void *str2, size_t n)

void *memmove(void *str1, const void *str2, size_t n)

参数

  • str1 – 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
  • str2 – 指向要复制的数据源,类型强制转换为 void* 指针。
  • n – 要被复制的字节数。
  • 返回值
    该函数返回一个指向目标存储区 str1 的指针。
    模拟实现
void* my_memmove(void* dest, const void* src, size_t count)
{
  assert(dest && src);
  char* pdest = (char*)dest;
  const char* psrc = (char*)src;
  if (pdest < psrc || *pdest >= *psrc + count)//没有发生内存重叠
  {
    while (count--)
    {
      *pdest++ = *psrc++;
    }
  }
  else//发生内存重叠
  {
    pdest = pdest + count - 1;
    psrc = psrc + count - 1;
    while (count--)
    {
      *pdest-- = *psrc--;
    }
  }
  return dest;
}

但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。什么是内存重叠?

内存重叠就是拷贝的目的地址和源地址有重叠

d3d16af37cd1e976c860e8ed15dfad4.png

蓝色部分为内存重叠区。

目录
相关文章
|
6月前
字符串函数
字符串函数
|
6月前
|
C语言
字符函数和字符串函数
字符函数和字符串函数
69 0
|
C语言 Python
字符函数和字符串函数(下)
字符函数和字符串函数(下)
53 0
字符函数和字符串函数(下)
|
11月前
|
C语言
字符函数和字符串函数(下)
字符函数和字符串函数(下)
|
11月前
|
C语言
字符函数和字符串函数(上)
字符函数和字符串函数
|
11月前
详解字符函数和字符串函数-1
详解字符函数和字符串函数
41 0
|
11月前
|
C语言
详解字符函数和字符串函数-2
详解字符函数和字符串函数
48 0
|
编译器 C语言 Python
字符函数和字符串函数(上)
字符函数和字符串函数(上)
46 0
|
C语言
字符函数和字符串函数详解(一)
字符函数和字符串函数详解
46 0