!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)

  • 求字符串长度

  • strlen

  • 长度不受限制的字符串函数

  • strcpy

  • strcat 

  • trcmp

  • 长度受限制的字符串函数介绍

  • strncpy

  • strncat

  • strncmp

  • 字符串查找

  • strstr

  • strtok

  • 错误信息报告

  • strerror

  • 不幸的gets函数和升级版的fgets函数

  • puts函数和fputs函数

  • 缓冲区

  • 结束键盘,文件,流输入

首先我们先来学习一下strlen函数!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第1张图片

  • strlen

  • !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第2张图片
  • 1.字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 含 '\0' )。

  • 2.参数指向的字符串必须要以 '\0' 结束。所以如果我们没有遇到\0,strlen会一直检索直到遇到\0 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第3张图片

  • 上述我们看到计算的值为60,是因为我们strlen函数在计算arr数组时没有遇到\0,所以产生了随机值60,那么我们看下内存是否存放了\0

  • !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第4张图片
  • 3.注意函数的返回值为size_t,是无符号的( 易错 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第5张图片

  • 我们看看上述答案是多少呢,是第一个选择还是第二个选择呢?

  • !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第6张图片

      答案是第二个选项

  • 4.学会strlen函数的模拟实现(下图是模拟实现思路)!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第7张图片

strcpy

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第8张图片

 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第9张图片

1.源字符串必须以 '\0' 结束。

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第10张图片

 想一想为什么出现这种现象(非法访问?)

 答案是因为这个函数的实现就必须是用'\0'结束,这里arr2的空间里不  知  道'\0'在哪,所以在拷贝的时候会出现bug,具体我们看下面的模拟 实现内容就明白了。

2.会将源字符串中的 '\0' 拷贝到目标空间。

   我们看看是否strcpy函数会把'\0'拷贝到目标空间???

   !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第11张图片

 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第12张图片

 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第13张图片

 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第14张图片

3.目标空间必须足够大,以确保能存放源字符串。

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第15张图片

因为超过的话会越界导致栈溢出

4. 目标空间必须可变。

为什么会出现非法访问? 

因为"hello"是个常量字符串,我们不能对他赋值和修改

5.学会模拟实现

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第16张图片

strcat

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第17张图片

 1.源字符串必须以 '\0' 结束。(类似,就不描述了)

 2.目标空间必须有足够的大,能容纳下源字符串的内容。(类似,就不描述了)

 3.目标空间必须可修改。(类似,就不描述了)

 4.字符串自己给自己追加,如何?

    我们试一下

     !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第18张图片

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第19张图片

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第20张图片

 但是为什么vs2019的库里可以,因为每个编译器封装的函数不一样,底层实现不一样

 5.学会模拟实现

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第21张图片

 strcmp

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第22张图片

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第23张图片

切记,字符串比较的话不是比较长度而是比较两两字符的大小,有一个大或小于或者等于就返回

学会模拟实现

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第24张图片

strncpy

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第25张图片

 1.拷贝num个字符从源字符串到目标空间。

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第26张图片

 2. 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第27张图片

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第28张图片

     想一想strncpy与strncp有什么优缺点?

     strncpy相较于strcpy,在拷贝字符的时候更加精确,且不容易出错

     但是他在一些特定场合时的执行效率比较低,因为封装的函数的代码更加复杂

     导致效率会降低;

strncat

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第29张图片

 思考一下strncat与strcat有什么区别

1.

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第30张图片!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第31张图片

 2.strncat相较于strcat追加的字符可以控制,也就说更加精确,但是执 行 效率相较于strcat低了。

3.学会模拟实现

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第32张图片

 strncmp

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第33张图片

 1.思考一下strncmp与strcmp有什么区别

strncmp相较于strcmp,在拷贝字符的时候更加精确,且不容易出错但是他在一些特定场合时的执行效率比较低,因为封装的函数的代码更加复杂

 2.学会模拟实现

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第34张图片

 3.利用字符串比较可以查找对应字符

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第35张图片

 strstr

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第36张图片

 1.字符串查找

 2.学会模拟实现

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第37张图片

 strtok

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

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第38张图片

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

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

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

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

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

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

那么我们来实现一下看看。

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第39张图片

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第40张图片

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

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第41张图片

 为什么这里要置为空指针,因为置为空指针后,strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标 记。

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第42张图片

 但是仔细想想我们这样切割是不是太麻烦了 

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第43张图片

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第44张图片

 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第45张图片

 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第46张图片

strerror

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

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第47张图片

 那么我们的错误码有什么用呢,主要是为了检查错误

那怎么用呢?

我们先介绍他的错误信息

 举一些例子

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第48张图片

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第49张图片

gets

在读取字符串时,scanf()和转换说明%s只能读取一个单词。可是在程序中经常要读取一整行输入,而不仅仅是一个单词。许多年前,gets()函数就用于处理这种情况。gets()函数简单易用,它读取整行输入,直至遇到换行符,然后丢弃换行符,存储其余字符,并在这些字符的末尾添加一个空字符使其成为一个C字符串。它经常和puts()函数配对使用,该函数用于显示字符串,并在末尾添加换行符。

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第50张图片

但是gets()函数有缺陷

 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第51张图片

  缓冲区溢出

 这是为什么呢?

 因为,gets()函数只知道数组的开始处,并不知道数组中有多少个元素。

 如果溢出过多,可能会改写其他内存的数据,导致bug

所以有了下面的fgets()函数

fgets

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第52张图片

fgets函数相较于gets可以读取到\n,不会丢弃

并且可以控制读取字符个数,更加精确,虽然效率会低一点,但是比较安全

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第53张图片

 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第54张图片

 fgets()函数的第2个参数指明了读入字符的最大数量。如果该参数的值是n,那么fgets()将读入n-1个字符,或者读到遇到的第一个换行符为止。

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第55张图片

puts

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第56张图片

puts是个输出函数,但是这个与printf有什么不同呢?

puts在输出的时候会在字符串的末尾自动加'\n'——换行符 

printf:printf函数从左往右读取,然后将先读取放到栈底,最后读取的放在栈顶,处理时候是从栈顶开始的.所我们看见的结果是,从右边开始处理的.

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第57张图片

 puts函数也会读取,但是他会在末尾加一个换行符

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第58张图片

 !!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第59张图片

 不过printf相较于puts虽然效率低,但是他的格式变换多,而puts比较单一,一般用printf函数更好

fputs

!!!教你如何搞懂字符串函数(详细,后期会讲函数栈帧)_第60张图片

fputs函数相较于puts不会自动在输出的末尾加\n-换行符

缓冲区

为什么要有缓冲区?首先,把若干字符作为一个块进行传输比逐个发送这些字符节约时间。其次,如果用户打错字符,可以直接通过键盘修正错误。当最后按下Enter键时,传输的是正确的输入。

 虽然缓冲输入好处很多,但是某些交互式程序也需要无缓冲输入。例如,在游戏中,你希望按下一个键就执行相应的指令。因此,缓冲输入和无缓冲输入都有用武之地。

缓冲分为两类:完全缓冲I/O和行缓冲I/O。完全缓冲输入指的是当缓冲区被填满时才刷新缓冲区(内容被发送至目的地),通常出现在文件输入中。缓冲区的大小取决于系统,常见的大小是512字节和4096字节。行缓冲I/O指的是在出现换行符时刷新缓冲区。键盘输入通常是行缓冲输入,所以在按下Enter键后才刷新缓冲区。

你可能感兴趣的:(c语言,visualstudio)