c语言学习第二十七课 ——一些内存函数与字符串函数

简介: c语言学习第二十七课 ——一些内存函数与字符串函数

strtok函数

592270ddb2704d8f8f43078def706205.png

char* strtok(char *str,char *sep)

返回的是分割符标记的起始位置

函数作用   给一个邮箱  kajsoijfdcoaioij@.com           @ 。被叫做分割符

该函数作用就是提取这些分割符。

第一的参数为字符串,sep参数是个字符串,定义了用做分割符字符的集合

53c130267e4c43a9ad9f1c35454ba4bb.png  例如

int main()
{
  char arr[] = " kajsoijfdcoaioij@.com ";
  const char* p = "@.";
  char bufer[30] = { 0 };
  char* str = strtok(bufer, p);
  strcpy(bufer, arr);
  //该函数会改变字符串中的分隔符为\0;
  strtok(bufer, p);
  //strtok传的第一个参数不为空指针时,读入,当遇到分割符时,变为\0,切割掉返回空指针,保c存分割符的位置,继续进行切割,寻找下一个分割符
  //常量i昂字符无法修改
  strtok(NULL, p);
  printf("%s\n", str);
  strtok(NULL, p);
  printf("%s\n", str);
  strtok(NULL, p);
  printf("%s\n", str);
  //
  char* str = NULL;
  for (str = strtok(bufer, p); str= NULL;str = strtok(NULL,p))
  {
    printf("%s\n", str);
  }
  return 0;
}

strerror函数

a7889810197540ebacdfe5a738be95e3.png

e9431c8cfe014b22b6b1e69a737ca884.png

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

char *strerror()

每一个错误码都有错误信息

c语言的库函数再调用失败的时候,会将一个错误码存放在一个叫error的变量中,当我们想知道调用库函数的时候发生了什莫错误,就可以把error里的错误码翻译为错误信息。 例

int main()
{
  char* p = strerror(0);
  printf("%s\n", p);
  char* p = strerror(1);
  printf("%s\n", p);
  char* p = strerror(2);
  printf("%s\n", p);
  char* p = strerror(3);
  printf("%s\n", p);
  return 0;
}

举例打印文件打开错误

int main()
{
  //打开文件
  FILE* p = fopen("text.txt", "r");//如果打开方式是“r”,若文件存在则打开成功,否则失败
  //这里未建立这样的文件
  if (p == NULL)
  {
    printf("打开失败,原因是%s\n",strerror(errno));//显示错误 errno中把错误码翻译成错误信息
    //perror函数  打印错误信息
    //perror("文件打开失败");把定义的错误信息后在打印错误信息,可以理解为printf+strerror结合函数。
  }
  //读写文件
  //关闭文件
  fclose(p);
  p = NULL;
  return 0;
}

这里还有许多常用的字符判断函数。其用法相似。

8abb01dd77c54e6d9777bfcbd7efd52a.png

df98fa0a714c4129accb92367c436ed2.png

isdigit

55cdf4f87d204a63920e9f76359ceea2.png

7abc8d39d13a4dbe8adab6fbba040be7.png

isspace     isxdigit   islower  issupper    isalpha   isaipha等的函数.

内存函数

不同于字符串函数,这里可以实现各种类型的数据的函数。

memcpy

3c22bd78b7b04080b9ab274467a1e733.png

fa4b2f4ee6864cc6a5bcdefdf7ca0c19.png

例如

int main()
{
  int arr1[] = { 1,2,3,4,5,6,7,8,9 };
  int arr2[] = { 0 };
  //memcpy,拷贝数据
  memcpy(arr2, arr1, 20);//把arr1中的5个整形拷贝到arr2中 , size_t num为所拷贝数据内存大小,
    float arr1[] = { 1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0 };
  float arr2[] = {0.0};
  memcpy(arr2, arr1, 12);//把arr1中的5个整形拷贝到arr2中 
  return 0;
}

函数实现

void* my_memcpy(const void*str,const void *ptr,size_t num)
{
  void* ret = str;
  assert(str && ptr);//断言判断是否为指针
  while (num--)
  {
       *(char*)str = *(char*)ptr;
     str = (char*)str + 1;
      ptr = (char*)str + 1;
  }
  return ret;
}

在内存重叠时使用memcpy可能出现其他结果,这时使用memmove,不会重现重叠,数据覆盖

例如  

memmove

2b8e13b8102648f8954b11bbd393a5a2.png

void* memmove(void* destinnation, void* source, size_tnum)

a3a9c6f54ea64672ba8ed97f93113954.png

int main()
{
  int  arr1[] = {1,2,3,4,5,6,7,8,9};
  int  arr2[] = { 1,2 };
  memmove(arr2+2, arr1, 12);//把arr1中的5个整形拷贝到arr2中 
  return 0;
}

函数实现

void* my_memmove(const void* str, const void* ptr, size_t num)
{
  //从前往后拷贝和从后往前拷贝
  //分情况讨论
  //当str<ptr  从前往后拷贝
  //当str>ptr  从后往前拷贝
  assert(str && ptr);
  void* ret = str;
  if (str < ptr)
  {   
    *(char*)str = *(char*)ptr;
    str = (char*)str + 1;
    ptr = (char*)str + 1;
  }
  else
  {
    //后->前
    while (num--)
    {
      *((char*)str + num) = *((char*)ptr + num);
    }
  }
  return ret;
}

这里存在分情况讨论是因为如图

4594c406215e4a9d8ce3d52eaea0227f.png

memcmp

1ce94f6f094245c1b653c0608a78c8d3.png

cecc5ab60d19407390cc9e9a703f98ab.png

void test()
{
  int arr[] = { 1,2,3,4,5,6,7,8,9 };
  int arr1[] = { 1,2,4,6 };
  int ret = memcmp(arr,arr1, 16);
  printf("%d\n", ret);
}

memset

19e4e168727749e2abe076dbb114d88b.png

025bb07699cc4d7fb5ade84ab9c5ad09.png

相关文章
|
9天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
34 6
|
13天前
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
34 6
|
19天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
80 12
|
11天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
33 1
|
16天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
1月前
|
C语言
【c语言】动态内存管理
本文介绍了C语言中的动态内存管理,包括其必要性及相关的四个函数:`malloc`、``calloc``、`realloc`和`free`。`malloc`用于申请内存,`calloc`申请并初始化内存,`realloc`调整内存大小,`free`释放内存。文章还列举了常见的动态内存管理错误,如空指针解引用、越界访问、错误释放等,并提供了示例代码帮助理解。
46 3
|
2月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
32 0
|
7月前
|
存储 C语言
C 语言函数完全指南:创建、调用、参数传递、返回值解析
函数是一段代码块,只有在被调用时才会运行。 您可以将数据(称为参数)传递给函数。 函数用于执行某些操作,它们对于重用代码很重要:定义一次代码,并多次使用。
215 3
|
2月前
|
C语言
C语言函数返回值详解
本文详细解析了C语言中函数返回值的概念与应用。从函数的基本定义入手,深入探讨了不同类型返回值的作用及意义,并提供了实用的编程示例,帮助读者更好地理解和使用函数返回值。通过本文,你将掌握如何有效利用返回值优化代码结构与功能实现。
|
6月前
|
存储 C语言
C语言的函数返回值和指针
C|函数返回值(区分各类值)和指针(区分各类存储空间)的细节