字符串函数和内存函数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;
}
相关文章
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
34 3
|
28天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
158 1
|
1月前
|
程序员 C语言
C语言内存函数精讲
C语言内存函数精讲
|
24天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
20 0
|
1月前
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
40 0
|
1月前
|
存储 C语言 C++
来不及哀悼了,接下来上场的是C语言内存函数memcpy,memmove,memset,memcmp
本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠复制,memmove处理重叠内存,memset用于填充特定值,memcmp用于内存区域比较。通过实例展示了它们的用法和注意事项。
66 0
|
1月前
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
65 0
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
374 0