【C生万物】 字符串&内存函数篇 (上)(二)

简介: 【C生万物】 字符串&内存函数篇 (上)

正文


8.strstr


https://legacy.cplusplus.com/reference/cstring/strstr/?kw=strstr


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

这个函数的作用就是寻找相等的字符串,返回指针类型

• 在 str1 中寻找 str2 ,找到了就返回指向 str1 中与 str2 相同字符的指针,如果没有(str2 不是 str1 的一部分),就返回 NULL

• 匹配过程不包括空字符串。


例子:

#include <stdio.h>
#include <string.h>
int main()
{
  char str[] = "This is a simple string";
  char* pch;
  pch = strstr(str, "simple");
  if (pch != NULL)
    strncpy(pch, "sample", 6);
  puts(str);
  return 0;
}

👁️‍🗨️输出结果:

a2e89f97c5a6b1f3c9807df63f3a5205_ba194f922f1d41a7820db7d54f5e487f.png


简单解释,在 str 中寻找字符串 simple,将其地址保存到 pch 中,再将 simple 替换为 sample,最终输出替换后的结果。


9.strtok


https://legacy.cplusplus.com/reference/cstring/strtok/?kw=strtok


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

这个函数是做字符串切分的

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

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

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

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

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

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


看着挺复杂的,其实... ...就是复杂的。

接下来看个例子,相信会好些:

#include <stdio.h>
#include <string.h>
int main()
{
  char str[] = "- This, a sample string.";
  char* pch;
  printf("Splitting string \"%s\" into tokens:\n", str);
  pch = strtok(str, " ,.-"); // 分割符可以是字符集合
  while (pch != NULL)
  {
    printf("%s\n", pch);
    pch = strtok(NULL, " ,.-");
  }
  return 0;
}

👁️‍🗨️输出结果:

3962452550d655aba52658e1c3853436_9cb2d5718f194502b2d936de95009652.png

这个例子就是将字符串 - This, a sample string. 按照 , - . 三个分隔符切割,注意进行多个字符的切割时,要进行 pch = strtok(NULL, " ,.-"); 操作,对应 strtok 函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记


10.memcpy


https://legacy.cplusplus.com/reference/cstring/memcpy/?kw=memcpy


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

这个 void 类型不是没有,而是可以接受多种类型


这个函数是复制数据用的


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

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

• 如果 source   和  destination   有任何的重叠,复制的结果都是未定义的。  


例子:


#include <stdio.h>
#include <string.h>
struct 
{
  char name[40];
  int age;
} person, person_copy;
int main()
{
  char myname[] = "Pierre de Fermat";
  /* using memcpy to copy string: */
  memcpy(person.name, myname, strlen(myname) + 1);// +1是要把'\0'拷贝上 
  person.age = 46;
  /* using memcpy to copy structure: */
  memcpy(&person_copy, &person, sizeof(person));
  printf("person_copy: %s, %d \n", person_copy.name, person_copy.age);
  return 0;
}

👁️‍🗨️输出结果:

858b01e051fe0c47747cb9390b914e75_1874ce8190e341559ccdb6aa218857be.png解释:定义了一个结构体,包含名字和年龄,先将 myname 中的内容拷贝到结构体的 name 成员中,再将整个结构体拷贝给自己(可拷贝类型有多种)。


11.memmove


https://legacy.cplusplus.com/reference/cstring/memmove/?kw=memmove


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

参数类型与 memcpy 是相同的,两者的不同在哪里呢?

• 差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的;

• 如果源空间和目标空间出现重叠,就得使用 memmove 函数处理。


也就是说,在不确定源空间和目标空间是否重叠的情况下,memmove 可以保证拷贝的内容是正确的,所以 memmove 相比 memcpy 更安全。

例子:

#include <stdio.h>
#include <string.h>
int main()
{
  char str[] = "memmove can be very useful......";
  memmove(str + 20, str + 15, 11);
  puts(str);
  return 0;
}

👁️‍🗨️输出结果:

386fa882d89dd6d5bda72de27bd04ff2_eccf8d864c40411586a07e56433335c7.png

这个例子可以充分说明源空间和目标空间存在重叠的时候可以保证拷贝成功。


12.memcmp


https://legacy.cplusplus.com/reference/cstring/memcmp/?kw=memcmp


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

看返回类型是 int 类型,啊哈,这个函数是比较两个数据的

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

例子:

#include <stdio.h>
#include <string.h>
int main()
{
  char buffer1[] = "DWgaOtP12df0";
  char buffer2[] = "DWGAOTP12DF0";
  int n;
  n = memcmp(buffer1, buffer2, sizeof(buffer1));
  // 注意:大写字符的ASCII码值 小于 小写字符的ASCII码值
  if (n > 0) 
    printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
  else if (n < 0) 
    printf("'%s' is less than '%s'.\n", buffer1, buffer2);
  else 
    printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
  return 0;
}

👁️‍🗨️输出结果:

86933551c89b12d3abed44de874b9bbd_a853bc3cf9c14346ba7cb43fe4337d8a.png

大写字符的ASCII码值 小于 小写字符的ASCII码值

所以才会有这样的结果,跟想想中的不一样... ...


总结:

这期主要是带大家认识各种常见的字符串处理函数,知道有这些好用的函数并且会应用就可以了,下期带大家尝试实现几个其中的函数。


码文不易

如果你觉得这篇文章还不错并且对你有帮助,不妨支持一波哦  💗💗💗


目录
相关文章
|
3月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
44 3
|
1月前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
64 6
|
2月前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
54 6
|
3月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
3月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
44 0
|
3月前
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
51 0
|
3月前
|
存储 C语言 C++
来不及哀悼了,接下来上场的是C语言内存函数memcpy,memmove,memset,memcmp
本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠复制,memmove处理重叠内存,memset用于填充特定值,memcmp用于内存区域比较。通过实例展示了它们的用法和注意事项。
88 0
|
2月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
368 1
|
1月前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
|
2月前
|
Java
JVM内存参数
-Xmx[]:堆空间最大内存 -Xms[]:堆空间最小内存,一般设置成跟堆空间最大内存一样的 -Xmn[]:新生代的最大内存 -xx[use 垃圾回收器名称]:指定垃圾回收器 -xss:设置单个线程栈大小 一般设堆空间为最大可用物理地址的百分之80

热门文章

最新文章