字符串函数和内存函数1

简介: 字符串函数和内存函数

前言

从语言对字符和字符串的处理时很频繁的,但是C语言本身是没有字符串类型的,字符串通常放在字符串常量中或者字符数组中,字符串常量适用于那些对它不做修改的字符串函数


1.求字符串长度

1.1 strlen

size_t strlen(const char* str);

size_t 就是 unsigned int 类型。

注意:

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

示例:

#include<stdio.h>
#include<string.h>
int main()
{
  int len = strlen("abcedf");
  printf("%d\n", len);//6
  char arr[] = "abc\0def";
  len = strlen(arr);
  printf("%d\n", len);//3
  char arr1[3] = { 'a','b','c' };//没有 '\0'
  len = strlen(arr1);
  printf("%d\n", len);//随机值
  return 0;
}


返回值是 size_t 类型

#include<stdio.h>
#include<string.h>//VS不写头文件,会把返回值当为int类型
int main()
{
  //strlen函数的返回值是size_t - 无符号整形
  if (strlen("abc") - strlen("abcdef") > 0)
  {
    printf(">\n");//输出
  }
  else
  {
    printf("<=\n");
  }
  return 0;
}

自己模拟实现strlen函数,3种方法

1.计数器

2.递归

3.指针-指针

#include<stdio.h>
#include<assert.h>
//1.计数器
int my_strlen1(const char* arr)
{
  assert(arr != NULL);
  int count = 0;
  while (*arr)
  {
    count++;
    arr++;
  }
  return count;
}
//2.递归
int my_strlen2(const char* arr)
{
  if (*arr != '\0')
  {
    return my_strlen2(arr + 1) + 1;
  }
  else
  {
    return 0;
  }
}
//3.指针-指针
int my_strlen3(const char* arr)
{
  char* start = arr;
  while (*arr != '\0')
  {
    arr++;
  }
  return arr - start;
}
int main()
{
  char arr[] = "bit";
  int ret = my_strlen3(arr);
  printf("%d\n", ret);
  return 0;
}

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

2.1 strcpy 字符串拷贝函数

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

把 source 处的字符串拷贝到 destination 处。

注意:

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

示例:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "abcdef";
  char arr2[20] = { 0 };
  strcpy(arr2, arr1);//arr2是目的地,拷贝到'\0',并且把'\0'拷贝过去 输出abcdef
  printf("%s\n", arr2);
  char arr3[] = "abc\0def";
  strcpy(arr2, arr3);//拷贝到'\0',并且把'\0'拷贝过去  输出abc
  printf("%s\n", arr2);
  //目标空间必须可变
  //char* p = "abcdefghi";
  //char arr4[20] = "hehe";
  //strcpy(p, arr4);//错误,p指向的是常量字符串,不能被修改
  return 0;
}

自己模拟实现 strcpy 函数

#include<stdio.h>
#include<assert.h>
//返回是目标空间的起始地址
char* my_strcpy(char* destination, const char* source)
{
  assert(destination && source);//不能为空
  int start = destination;
  while (*destination++ = *source++);
  return start;
}
int main()
{
  char arr1[] = "abcdef";
  char arr2[20] = "0";
  my_strcpy(arr2,arr1);
  printf("%s\n", arr2);
  printf("%s\n", my_strcpy(arr2, arr1));
  return 0;
}

2.2 strcat 字符串追加函数

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

将 source 处字符串追加到 destination 处

注意:

  • 源字符串必须以‘\0'结束。
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改。
  • 字符串自己不能给自己追加。

示例:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[20] = "hello ";
  char arr2[] = "world";
  //追加
  strcat(arr1, arr2);//从字符串的'\0'开始追加
  printf("%s\n", arr1); //输出 hello world
  return 0;
}

我们通过自己模拟实现,就可以理解为什么不可以自己给自己追加:

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* desination, const char* source)
{
  assert(desination && source);
  char* start = desination;
  while (*desination)//找到目标空间的第一个'\0'
  {
    desination++;
  }
  while (*desination++ = *source++);//拷贝字符串
  return start;
}
int main()
{
  char arr1[20] = "hello ";
  char arr2[] = "world"; 
  my_strcat(arr1, arr2);
  printf("%s\n", arr1);
  return 0;
}

自己给自己追加,desination 和 source 相同,会修改自己最后的'\0',使得拷贝遍历的时候找不到自己的'\0'。

2.3 strcmp

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


注意:


C语言标准规定


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

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

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

如何比较两个字符串:


比较的是相同位置上字符的ASCII码值,相等比较下一位,如果比到'\0'都相等,返回0。否则第一个ASCII码值大则返回大于0的数字,则小返回小于0的数字。


示例:

#include<stdio.h>
int main()
{
  if ("abcdef" == "cdefg");//可以比较,比较的是两个常量字符串的首字符地址
  //比较两个字符串的内容的时候,应该使用strcmp
  char arr1[] = "abcdef";
  char arr2[] = "cdefg";
  int ret = strcmp(arr1, arr2);//比较的是对应位置上字符的ASCII码值,
  //相等比较下一位,如果比到'\0'都相等,返回0
  //arr1的ASCII码值大,返回大于0的数字,
  //arr1的ASCII码值小,返回小于0的数字
  printf("%d\n", ret);
  return 0;
}

自己模拟实现:

#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
  assert(str1 && str2);
  while (*str1 == *str2)
  {
    if (*str1 == '\0')
    {
      return 0;
    }
    str1++;
    str2++;
  }
  //return *str1 - *str2;//没有说必须返回-1,或1
  if (*str1 > *str2)
  {
    return 1;
  }
  else
    return -1;
}
int main()
{
  char arr1[] = "qwer";
  char arr2[] = "asdf";
  int ret = my_strcmp(arr1, arr2);
  printf("%d\n", ret);
  return 0;
}


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

3.1 strncpy

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


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

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

示例:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "abcdef";
  char arr2[5] = "xxxx";
  //数字大于arr1长度是会补\0的
  strncpy(arr2, arr1, 3);//abcx
  printf("%s\n", arr2);
  return 0;
}

3.2 strncat

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

将 source 处的前num的字符追加到destination字符串后面'\0'处。

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[20] = "hello ";
  char arr2[] = "world";
  //数字大于arr2长度 不会再补多余的'\0'
  strncat(arr1, arr2, 3);//追加完后面会补'\0'
  printf("%s\n", arr1);//输出hello wor
  return 0;
}

strncmp可以自己给自己追加。num写成自身长度。

3.3 strncmp

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

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

返回值:

示例:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "abcdef";
  char arr2[] = "abc";
  //输入要比较几个字符
  int ret = strncmp(arr1, arr2, 3);
  printf("%d\n", ret);
  return 0;
}


4.字符串查找

4.1 strstr

char* strstr(const char* str1, const char* str2);

在str1中找str2首次出现的地址 ,没有找到返回空指针

示例:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr1[] = "abcdef";
  char arr2[] = "bcd";
  char* p = strstr(arr1, arr2);
  if (p == NULL)
  {
    printf("没有找到\n");
  }
  else
  {
    printf("%s\n", p);//bcdef
  }
  return 0;
}

自己模拟实现

#include<stdio.h>
char* my_strstr(const char* str1, const char* str2)
{
  while (*str1!='\0')
  {
    const char* p1 = str1;
    const char* p2 = str2;
    while (*p1 == *p2)
    {
      if (*(p2+1) == '\0')
      {
        return (char*)str1;
      }
      p1++;
      p2++;
    }
    str1++;
  }
  return NULL;
}
int main()
{
  char arr1[] = "abcdef";
  char arr2[] = "bcd";
  char* p = my_strstr(arr1, arr2);
  if (p == NULL)
  {
    printf("没有找到\n");
  }
  else
  {
    printf("%s\n", p);//cdef
  }
  return 0;
}
相关文章
|
11天前
|
存储 算法 C语言
C库函数详解 - 内存操作函数:memcpy()、memmove()、memset()、memcmp() (一)
`memcpy()` 和 `memmove()` 是C语言中的两个内存操作函数。 `memcpy()` 函数用于从源内存区域复制指定数量的字节到目标内存区域。它不处理内存重叠的情况,如果源和目标区域有重叠,结果是未定义的。函数原型如下: ```c void *memcpy(void *dest, const void *src, size_t num); ```
29 6
|
2天前
|
安全 编译器 C语言
【再识C进阶3(下)】详细地认识字符分类函数,字符转换函数和内存函数
【再识C进阶3(下)】详细地认识字符分类函数,字符转换函数和内存函数
|
7天前
|
存储 算法 C语言
C语言指针与二维数组在函数参数传递和动态内存管理中的应用
C语言指针与二维数组在函数参数传递和动态内存管理中的应用
17 0
|
8天前
|
C语言
C语言(11)----内存函数
C语言(11)----内存函数
14 1
字符串和内存函数(下)
字符串和内存函数(下)
|
8天前
|
C++
字符串和内存函数(上)
字符串和内存函数(上)
|
8天前
|
存储 测试技术 C语言
C语言内存管理函数研究
C语言内存管理函数研究
17 0
|
9天前
|
C语言
C语言内存操作函数
C语言内存操作函数
16 1
|
11天前
|
存储 C语言
C库函数详解 - 内存操作函数:memcpy()、memmove()、memset()、memcmp() (二)
`memset()`是一个C语言库函数,用于将指定内存区域的字节设置为特定值。函数原型为`void *memset(void *ptr, int value, size_t num)`,参数分别为指向内存起始位置的指针、要设置的值和设置的字节数。`memcmp()`函数则用于比较两个内存区域,返回值表示比较结果,原型为`int memcmp(const void *ptr1, const void *ptr2, size_t num)`。它比较指定字节数的内存,并根据比较结果返回整数值。
28 4