字符串函数和内存函数2

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

4.2 strtok

char* strtok(char* str,const char* delimiters);

对有分割符的字符串操作,将它们分隔开来。

用法:


delimiters参数是个字符串,定义了用作分隔符的字符集合

第一个参数指定一个字符串,它包含了0个或者多个由delimiters字符串中一个或者多个分隔符分割的标记。

strtok函数找到str中的下一个标记,并将其用'\0'结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)

strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,把它修改为'\0',strtok函数将保存它在字符串中的位置。strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。

如果字符串中不存在更多的标记,则返回NULL指针。


示例:

#include<stdio.h>
#include<string.h>
int main()
{
  char arr[] = "xilanhua@csdn.net";
  char buf[30] = { 0 };
  strcpy(buf, arr);//后面操作buf,不会修改原数据
  const char* p = "@.";//const 更严谨,分割符的字符合集
  char* str = strtok(buf, p);//传入buf不为空,返回最开始的地址'x',把第一个分割符'@'改为'\0',并保存第一个分割符'@'的位置
  printf("%s\n", str);
  str = strtok(NULL, p);//传入空指针,返回刚才保存的位置下一个字符位置'c',从刚刚保存的位置开始寻找下一个分割符'.',改为'\0',保存这个位置。
  printf("%s\n", str);
  str = strtok(NULL, p);//传入空指针,返回刚才保存的位置下一个字符位置's',从刚刚保存的位置开始寻找下一个分割符'\0',保存这个位置
  printf("%s\n", str);
  str = strtok(NULL, p);//返回空指针
  return 0;
}

可以发现这样有很多重复代码,我们可以利用如果字符串中不存在更多的标记,则返回NULL指针,这条性质,循环打印

#include<stdio.h>
#include<string.h>
int main()
{
  char arr[] = "xilanhua@csdn.net";
  char buf[30] = { 0 };
  strcpy(buf, arr);//后面操作buf,不会修改原数据
  const char* p = "@.";//const 更严谨
  char* str = NULL;
  for (str = strtok(buf, p); str != NULL; str = strtok(NULL, p))//最后会strtok返回NULL
  {
    printf("%s\n", str);
  }
  return 0;
}

可以发现strtok函数有记忆功能,可以记住上次调用保存的位置,那么可以说明使用了静态变量

5.错误信息报告

5.1 strerror

char* strerror(int errnum);


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

每个错误码都有对应的错误信息。

示例:

C语言的库函数在调用失败的时候,会将一个错误码存放在一个叫:errno的变量中

当我们想知道调用库函数的时候发生了什么错误信息

就可以将:errno中的错误码翻译成错误信息,使用时要包含头文件<errno.h>

没有错误是0

在文件操作时的使用情况。

perror 函数相当于printf 函数和 strerror 函数一起使用的效果。

6.字符操作

以下函数都要包含头文件 <ctype.h>

字符分类函数:

1691642969045.png

字符转换函数:

1. int tolower(int c);//转换为小写
2. int toupper(int c);//转换为大写


7.内存操作函数

字符串相关函数都是对字符串进行操作的,而下面函数都是对内存直接操作的函数,也需要包含头文件<string.h>。


7.1 memcpy

内存拷贝函数

void* memcpy(void* destination,const void* source,size_t num);

函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。

这个函数在遇到'\0'的时候并不会停下来。

如果source和destination有任何的重叠,复制的结果都是C语言标准未定义的。有重叠的应该使用memmove函数

示例:

#include<stdio.h>
#include<assert.h>
#include<string.h>
int main()
{
  int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
  int arr2[8] = { 0 };
  //把arr1中的前五个数据拷贝到arr2中  是整形不能用strcpy
  memcpy(arr2,arr1,20);//从arr1中拷贝20个字节放到arr2中
  for (int i = 0; i < 8; i++)
  {
    printf("%d ", arr2[i]);
  }
    return 0;
}

自己模拟实现memmove函数:

void* my_memcpy(void* destination, const void* source, size_t num)
{
  void* ret = destination;
  assert(destination && source);
  while (num--)
  {
    *(char*)destination = *(char*)source;
    destination = (char*)destination + 1;
    source = (char*)source + 1;
  }
  return ret;
}

7.2 memmove

void* memmove(void* destination,const void* source,size_t num);
  • 和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠,就得使用memmove函数处理。

当我们拷贝有重叠部分的内容时,比如:

int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memcpy(arr1 + 2, arr1, 20);


可能会出现这种情况,没有达到想要的效果

所以要使用memcpy函数

#include<stdio.h>
#include<string.h>
int main()
{
  int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
  memmove(arr1 + 2, arr1, 20);
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    printf("%d ", arr1[i]);
  }
}

自己模拟实现memmove函数

void* my_memmove(void* dest, const void* src, size_t num)
{
  void* ret = dest;
  assert(dest && src);
  if (dest > src)//从后往前拷贝
  {
    while (num--)
    {
      *((char*)dest + num) = *((char*)src + num);
    }
  }
  else//从前往后拷贝
  {
    while (num--)
    {
      *(char*)dest = *(char*)src;
      dest = (char*)dest + 1;
      src = (char*)src + 1;
    }
  }
  return ret;
}

注意:


在内存重叠的时候,使用memcpy可能会出现意想不到的结果建议在内存重叠的情况,使用memmove函数


C语言:memcpy拷贝不重叠的内存,重叠的就交给memmove


memmove 包含 memcpy 的功能


vs上可以使用memcpy操作重叠内容,但不能保证其他编译器可以。


7.3 memset

void* memset(void* ptr, int value, size_t num);

将ptr指向的空间的前num个字节设置为value,以字节为单位设置内存。

示例:

 

7.4 memset

int memcmp(const void* ptr1, const void* ptr2, size_t num);


比较从ptr1和ptr2指针开始的num个字节

返回值如下 :与 strcmp 和 strncmp 都类似

示例:

#include<string.h>
#include<stdio.h>
int main()
{
  int arr1[] = { 1,2,3,4,5 };
  int arr2[] = { 1,2,3,4,6 };
  int ret = memcmp(arr1, arr2, 16);
  printf("%d\n", ret);//0 相等
  ret = memcmp(arr1, arr2, 17);
  printf("%d\n", ret);//小于0
  return 0;
}

本篇结束

相关文章
|
2月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
41 3
|
21天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
49 6
|
2月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
2月前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
2月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
363 1
|
2月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
40 0
|
2月前
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
48 0
|
2月前
|
存储 C语言 C++
来不及哀悼了,接下来上场的是C语言内存函数memcpy,memmove,memset,memcmp
本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠复制,memmove处理重叠内存,memset用于填充特定值,memcmp用于内存区域比较。通过实例展示了它们的用法和注意事项。
78 0
|
2月前
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
80 0
|
28天前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
232 1