C语言之字符串,内存操作函数详解(一)

这篇具有很好参考价值的文章主要介绍了C语言之字符串,内存操作函数详解(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C语言学习分享⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习更多C语言知识
  🔝🔝


C语言之字符串,内存操作函数详解(一)



1. 前言🚩

C语言的标准库为我们提供了丰富的字符串操作函数与内存操作函数,有我们熟悉的 strlen ,strcpy ,也有我们不熟悉的 strchr , strstr 等.这里我们将一一为大家讲解.初阶的字符串函数我们会讨论自我实现,后面的高阶函数我们只给大家做介绍,希望我的文章能够帮到你.

我们这里学习字符串函数和内存操作函数都在cplusplus上查看定义Cplusplus网站


2. strlen函数🚩

先来看定义:

C语言之字符串,内存操作函数详解(一)
这个函数很明了,就是求字符串长度的函数,并且字符串的结束标志: '\0’不算在内

注意strlen返回一个类型为size_t 的值。这个类型是在头文件stddef.h中定义的,它是一个无符号整数类型。在表达式中使用无符号数可能导致不可预料的结果。例如,下面两个表达式看上去是相等的:

char x[]="abcdef";
char y[]="xyz";
if(strlen(x)>=strlen(y))//式子1
{
	...
}
if(strlen(x)-strlen(y)>=0)//式子2
{
	...
}

式子2是不能用于判断字符串x和字符串y谁的长度大的,因为strlen函数的返回值是无符号整型,两个无符号整型的数相减的结果也一定是无符号整型,所以不管是字符串x长度小于字符串y还是大于字符串y,式子2都是恒为真!

如果把strlen的返回值强制类型转换为 int 就可以消除这个问题.


2.1 strlen函数的自我实现🏁

size_t my_strlen(const char* p)//加上const表示我们不应该修改这个字符串
{
	unsigned int count = 0;
	int i = 0;
	while (p[i] != '\0')
	{
		count++;
		i++;
	}
	return count;
}

因为这个函数比较容易理解,所以不做过多解释


3. strcpy函数🚩

它的原型如下:

C语言之字符串,内存操作函数详解(一)

这个函数把参数src字符串复制到dst参数。如果参数src和dst在内存中出现重叠,其结果是未定义的。由于dst参数将进行修改,所以它必须是个字符数组或者是一个指向动态分配内存的数组的指针,不能使用字符串常量。

目标参数的以前内容将被覆盖并丢失。即使新的字符串比dst原先的内存更短,由于新字符串是以NUL字节结尾,所以老字符串最后剩余的几个字符也会被有效地删除。

警告:程序员必须保证目标字符数组的空间足以容纳需要复制的字符串。如果字符串比数组长,多余的字符仍被复制,它们将覆盖原先存储于数组后面的内存空间的值。strcpy无法解决这个问题,因为它无法判断目标字符数组的长度。


3.1 strcpy函数的自我实现🏁

char* my_strcpy(char *dst,const char *src)
{
	assert(dst != NULL);
	assert(src != NULL);
	char *ret = dst;
	while((* dst++ = * src++) != '\0') 
		;
	return ret;
}

这里需要注意的是,我们把src里面的内容拷贝到dst中,所以我们是不希望src的内容发生改变的,所以我们加上const,并且strcpy函数的返回值是目标字符串的起始位置的地址,所以这里我们用char*


4. strcat函数🚩

先看函数原型:

C语言之字符串,内存操作函数详解(一)

strcat函数要求dst参数原先已经包含了一个字符串(可以是空字符串)。它找到这个字符串的末尾,并把src字符串的一份拷贝添加到这个位置。如果src和dst的位置发生重叠,其结果是未定义的。

警告:和前面一样,程序员必须保证目标字符数组剩余的空间足以保存整个源字符串。但这次并不是简单地把源字符串的长度和目标字符数组的长度进行比较,你必须考虑目标数组中原先存在的字符串。


4.1 strcat函数的自我实现🏁

char* my_strcat(char* dest, const char* src)
{
	char* begin = dest;
	//第一步、寻找目标字符串中的'\0'
	while (*dest)
	{
		dest++;
	}
	//第二步、追加源字符串并包含\0
	while (*dest++ = *src++)
	{
		;
	}
	return begin;
}

4.2 函数的返回值🏁

strcpy和strcat都返回它们第1个参数的一份拷贝,就是一个指向目标字符数组的指针。由于它们返回这种类型的值,所以你可以嵌套地调用这些函数,如下面的例子所示:

char dst = ...;
char a = ...;
char b = ...;
strcat(strcpy(dst,a),b);


5. strcmp函数🚩

先看函数原型:

C语言之字符串,内存操作函数详解(一)

比较两个字符串涉及对两个字符串对应的字符逐个进行比较,直到发现不匹配为止。那个最先不匹配的字符中较“小”(也就是说,在字符集中的序数较小)的那个字符所在的字符串被认为“小于”另外一个字符串。如果其中一个字符串是另外一个字符串的前面一部分,那么它也被认为“小于”另外一个字符串,因为它的NUL结尾字节出现得更早。这种比较被称为“词典比较”,对于只包含大写字母或只包含小写字母的字符串比较,这种比较过程所给出的结果总是和我们日常所用的字母顺序的比较相同。

int strcmp(char const* s1,char const* s2)

如果s1小于s2,strcmp函数返回一个小于零的值。如果s1大于s2,函数返回一个大于零的值。如果两个字符串相等,函数就返回零。

警告:

  • 注意标准并没有规定用于提示不相等的具体值。它只是说如果第1个字符串大于第2个字符串就返回一个大于零的值,如果第1个字符串小于第2个字符串就返回一个小于零的值。一个常见的错误是以为返回值是1和-1,分别代表大于和小于。但这个假设并不总是正确的。
  • 由于strcmp并不修改它的任何一个参数,所以不存在溢出字符数组的危险。但是,和其他不受限制的字符串函数一样,strcmp函数的字符串参数也必须以一个NUL字节结尾。如果并非如此,strcmp就可能对参数后面的字节进行比较,这个比较结果将不会有什么意义.

5.1 strcmp函数的自我实现🏁

int Strcmp(char* str1, char* str2)//strcmp函数具体实现。
{
    while ((*str1 != '\0') && (*str1 == *str2))//判断字符串是否结束。
    {
        str1++;
        str2++;//
    }
    return *str1 - *str2;
}

C语言并没有规定strcmp的返回值是-1或者1,只要是大于0,或者小于0,直接返回即可


6. 长度受限的字符串函数🚩

标准库还包含了一些函数,它们以一种不同的方式处理字符串。这些函数接受一个显式的长度参数,用于限定进行复制或比较的字符数。这些函数提供了一种方便的机制,可以防止难以预料的长字符串从它们的目标数组溢出。这些函数的原型如下:

C语言之字符串,内存操作函数详解(一)
C语言之字符串,内存操作函数详解(一)
C语言之字符串,内存操作函数详解(一)

很明显,在以上函数中加一个n就是限制长度的意思,strcpy加上n就是只能拷贝num个字符串,以此类推
如果源参数和目标参数的地址发生重叠,strncpy和strncat的结果都是未定义的(危险的)


6.1 strncpy函数的注意事项🏁

和strcpy一样,strncpy把源字符串的字符复制到目标数组。然而,它总是正好向dst写入len个字符。如果strlen( src )的值小于len,dst数组就用额外的NUL字节填充到len长度。如果strlen( src )的值大于或等于len,那么只有len个字符被复制到dst中。注意!它的结果将不会以NUL字节结尾

警告的总结:

  • strncpy调用的结果可能不是一个字符串,因此字符串必须以NUL字节结尾。如果在一个需要字符串的地方(例如strlen函数的参数)使用了一个不是以NUL字节结尾的字符序列,会发生什么情况呢?strlen函数将无法知道NUL字节是没有的,所以它将继续进行查找,一个字符接一个字符,直到它发现一个NUL字节为止。或许它找了几百个字符才找到,而strlen函数的这个返回值从本质上说是一个随机数。或者,如果函数试图访问系统分配给这个程序以外的内存范围,程序就会崩溃。
  • 这个问题只有当你使用strncpy函数创建字符串,然后或者对它们使用str开头的库函数,或者在printf中使用%s格式码打印它们时才会发生。在使用不受限制的函数之前,你首先必须确定字符串实际上是以NUL字节结尾的。

6.2 strncat函数和strncmp的注意事项🏁

  • 尽管strncat也是一个长度受限的函数,但它和strncpy存在不同之外。它从src中最多复制len个字符到目标数组的后面。但是,strncat总是在结果字符串后面添加一个NUL字节,而且它不会像strncpy那样对目标数组用NUL字节进行填充。注意目标数组中原先的字符串并没有算在strncat的长度中。strncat最多向目标数组复制len个字符(再加一个结尾的NUL字节),它才不管目标参数除去原先存在的字符串之后留下的空间够不够。
  • 最后,strncmp也用于比较两个字符串,但它最多比较len个字节。如果两个字符串在第len个字符之前存在不相等的字符,这个函数就像strcmp一样停止比较,返回结果。如果两个字符串的前len个字符相等,函数就返回零。


7. 字符串查找基础🚩

标准库中存在许多函数,它们用各种不同的方法查找字符串。这些各种各样的工具给了C程序员很大的灵活性!
下面我就给大家介绍几个字符串函数的用法:


7.1 查找一个字符🏁

在一个字符串中查找一个特定字符最容易的方法是使用 strchr和strrchr函数,它们的原型如下所示:

C语言之字符串,内存操作函数详解(一)


C语言之字符串,内存操作函数详解(一)

注意它们的第2个参数虽然是一个整型值。但是C语言中字符其实就是一个小整型,所以可以用整型来存储字符值。strchr在字符串str中查找字符ch第1次出现的位置,找到后函数返回一个指向该位置的指针。如果该字符并不存在于字符串中,函数就返回一个NULL指针。strrchr的功能和strchr基本一致,只是它所返回的是一个指向字符串中该字符最后一次出现的位置(最右边那个)。


7.2 查找任意几个字符🏁

strpbrk是个更为常见的函数。它并不是查找某个特定字符,而是查找任何一组字符第1次在字符串中出现的位置。它的原型如下:

C语言之字符串,内存操作函数详解(一)

这个函数返回一个指向str中第1个匹配group中任何一个字符的字符位置。如果未找到匹配,函数返回一个NULL指针。如果你不理解它的意思,我们这里写一段代码来理解一下:

#include <stdio.h>
#include <string.h>
int main()
{
    char str[] = "This is a sample string";
    char key[] = "aeiou";
    char* pch;
    printf("Vowels in '%s': ", str);
    printf("\n");
    pch = strpbrk(str, key);
    while (pch != NULL)
    {
        printf("%c ", *pch);
        pch = strpbrk(pch + 1, key);
        printf("\n");
    }
    printf("\n");
    return 0;
}

这里字符串str中出现的字符串key中的第一个字符是 “This” 中的 ‘i’ ,第二个字符是 “is” 里面的 ‘i’ .第三次出现的是字符 ‘a’,以此类推,那么我们设计的代码会将key字符串中在str字符串出现过的字符按顺序打印,注意这里不是先找key字符串中的第一个字符 ‘a’,而是从str字符串中找 key字符串中能匹配的所有字符的第一个那么代码会打印出:

C语言之字符串,内存操作函数详解(一)


7.3 查找一个字串🏁

为了在字符串中查找一个字串,我们可以使用strstr函数,它的原型如下:

C语言之字符串,内存操作函数详解(一)

这个函数在s1中查找整个s2第1次出现的起始位置,并返回一个指向该位置的指针。如果s2并没有完整地出现在s1的任何地方,函数将返回一个NULL指针。如果第2个参数是一个空字符串,函数就返回s1。

标准库中并不存在strrstr或strrpbrk函数。不过,如果你需要它们,它们是很容易实现的。下面的程序显示了一种实现strrstr的方法。这个技巧同样也可以用于实现strrpbrk。


// 在字符串s1中查找字符串s2最右出现的位置,并返回一个指向该位置的指针。
#include <string.h>

char*
my_strrstr( char const *s1, char const *s2 )
{
    register char*last;
    register char*current;    
     //把指针初始化为我们已经找到的前一次匹配位置。    
    last = NULL;
    //只在第2个字符串不为空时才进行查找,如果S2为空,返回NULL。    
    if( *s2 != '\0' ){      
      // 查找s2在s1中第1次出现的位置。
      current = strstr( s1, s2 );
    // 我们每次找到字符串时,让指针指向它的起始位置。然后查找该字符串下一个匹配位置。
    
          while( current != NULL ){
            last = current;
            current = strstr( last + 1, s2 );
          }
      }
      //返回指向我们找到的最后一次匹配的起始位置的指针。
      return last;
}

8. 总结🚩

字符串操作函数和内存操作函数的内容十分多且冗杂,我们把高阶字符串查找和字符查找,内存操作函数放在下一章来讲解,希望我的内容能帮助到你文章来源地址https://www.toymoban.com/news/detail-480123.html

🔎 下期预告: 高阶字符串函数与内存操作函数 🔍
\

到了这里,关于C语言之字符串,内存操作函数详解(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 字符串函数+内存函数(详解)

    本期带大家一起来学习字符串函数+内存函数😀 😃 😄 1. 求字符串长度 strlen🚀🚀 字符串 已经 ‘\\0’ 作为结束标志 ,strlen函数返回的是在字符串中 ‘\\0’ 前面出现的字符个数(不包含 ‘\\0’ )。 strlen在库里面的参数是如此的 ⌛️⌛️ 接下来我们来模拟实现strlen ,接下来

    2023年04月17日
    浏览(43)
  • <C语言> 字符串内存函数

    C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串 或者 字符数组 中。 字符串常量 适用于那些对它不做修改的字符串函数. 注意:字符串函数都需要包含头文件string.h strlen() 函数用于计算字符串的长度,即字符串中字符

    2024年02月15日
    浏览(47)
  • 字符串函数和内存函数详解(2)

    🐵本文会将会对剩余的 字符串库函数 和 内存函数 进行讲解 strstr函数原型: strstr用于在字符串中找子串,strstr会返回str1中出现str2的起始地址,如果在str1中没有找到str2,则返回空指针 strstr会返回arr1中第一次出现arr2的地址,这里就是\\\'l\\\'的地址,将其传给指针ret,在打印时

    2024年02月07日
    浏览(42)
  • C/C++字符函数和字符串函数详解————内存函数详解与模拟

    个人主页:点我进入主页 专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶 C语言刷题 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 1.前言 2 .memcpy函数 3.memmove函数 4.memset函数  5.memcmp函数            前面学习了关

    2024年02月08日
    浏览(57)
  • C语言进阶---字符串+内存函数

    重点介绍处理字符和字符串的库函数的使用和注意事项。 求字符串长度 strlen() 长度不受限制的的字符串函数 strcpy() strcat() strcmp() 长度受限制的的字符串函数 strncpy() strncat() strncmp() 字符串查找 strstr() strtok() 错误信息报告 strerror() 字符操作 内存操作函数 memcpy() memmove() memset(

    2024年02月12日
    浏览(53)
  • 进阶C语言——字符串和内存函数

    今天我们学点库函数 字符函数和字符串函数 求字符串长度函数-strlen strlen需要的头文件是string.h ,那它的作用是什么呢?? 他是来求字符串长度的,统计的是’\\0’前的字符串长度 size_t是无符号的意思 学会了strlen函数怎么使用,那我们现在模拟实现一下strlen 之前讲过三种方

    2024年02月16日
    浏览(50)
  • 【C语言】字符函数与字符串函数以及内存函数 { 超详细攻略,一篇学会 }

    今日分享:字符、字符串函数和内存函数 内存函数 就是对内存进行操作的函数 字符串函数 就是对字符串进行操作的函数 字符函数 就是对字符进行操作的函数 str 前缀的函数是字符串函数,头文件string.h mem 前缀的函数是内存函数,头文件stdlib.h 字符分类函数包含在 ctype.h 头

    2024年03月18日
    浏览(59)
  • 【c语言:常用字符串函数与内存函数的使用与实现】

    简介:本篇文章是对C语言中常用的字符串函数和内存函数的学习以及模拟实现 文档内容来自:https://legacy.cplusplus.com/ 字符串以 ‘\\0’ 作为结束标志, strlen函数返回的是在字符串中 ‘\\0’ 前⾯出现的字符个数( 不包含 \\\'\\0\\\' )。 参数指向的字符串必须要以 ‘\\0’ 结束。 注意函

    2024年02月04日
    浏览(46)
  • C语言字符函数和字符串函数详解

           Hello, 大家好,我是一代,今天给大家带来有关字符函数和字符串函数的有关知识        所属专栏:C语言        创作不易,望得到各位佬们的互三呦 在C语言中有一些函数是专门为字符设计的,这些函数的使用都需要包含一个头文件ctype.h 如:(注:以下函数原型都

    2024年03月20日
    浏览(53)
  • C语言——详解字符函数和字符串函数(二)

    Hi,铁子们好呀!之前博主给大家简单地介绍了部分 字符和字符串函数 ,那么这次,博主将会把这些字符串函数给大家依次讲完! 今天讲的具体内容如下: 6.1.1 strcmp 函数介绍 它的函数原型如下: 具体的函数介绍如下图所示: 从图中我们得知: - 如果第一个字符串 PTR1 大于

    2024年04月10日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包