栏目分类

热点资讯

新闻

你的位置:kaiyun欧洲杯app(官方)官方网站·IOS/安卓通用版/手机APP下载 > 新闻 > kaiyun欧洲杯app(官方)官方网站·IOS/安卓通用版/手机APP下载文献输入缓冲区只可被读取数据-kaiyun欧洲杯app(官方)官方网站·IOS/安卓通用版/手机APP下载

kaiyun欧洲杯app(官方)官方网站·IOS/安卓通用版/手机APP下载文献输入缓冲区只可被读取数据-kaiyun欧洲杯app(官方)官方网站·IOS/安卓通用版/手机APP下载

发布日期:2024-05-08 05:23    点击次数:167

上期著作

《C道话输入输出流(9)无阵势输入输出函数的先容和代码实战》

《C道话输入输出流(8) 三种I/O时势和fread、fwrite、feof、ferror》

写在ungetc函数之前

C道话步伐库提供了无数的把数据写入到文献的输出函数,以及从文献读取数据的输入函数。

写入数据其实是写入到文献输出缓冲区,系统会自动将数据写入到文献保存,或者手动强制写入(fflush函数),由此可见,文献输出缓冲区只可被内存中的数据写入。

读取数据是从文献输入缓冲区读取数据,并莫得从文献本人中读取数据。当缓冲区中莫得要读取的数据,系统才会从文献中把需要的数据读取到缓冲区,散失缓冲区之前的数据,然后再传送给读取函数,以保证其读取到需要的值,如若文献中莫得需要读取的值,就复返不实信息,由此可见,文献输入缓冲区只可被读取数据。

C道话步伐库却提供了一个独特的函数,不错将一个字符从内存回写到文献输入缓冲区,下一次读取操作就会自动从回写到输入缓冲区中的这个字符运行轨则读取。

ungetc函数

ungetc函数中的“unget”,即是即是get(读取)的反义词,用以强调数据是写回到输入缓冲区的,和写入到文献输出缓冲区的函数分离开。’c’是字符character的含义,示意只可回写一个字符。咱们来看下函数原型:

int ungetc( int ch, FILE *fp);

ch即是要写回到文献输入缓冲区的字符的ASCII码值,fp是联系的文献对象。如若ch得胜放入到输入缓冲区,函数复返该字符的ASCII码值,如若失败则复返EOF文献收敛标识。

对于ungetc函数的重点

重点1

网上绝大部分教程皆把ch参数阐扬成是从输入缓冲区中读取的字符,然后通过ungetc函数回退到输入缓冲区,这是不实的!ch不但包含这种情况,还不错把内存中的字符回写。

重点2

ungetc 函数将字符放回到输入流中,并不是径直出动文献指针到这个字符的物理位置。履行上,ungetc 的操作是在里面缓冲区中进行的,而不是在文献本人。当你调用 ungetc 时,它并不会改换文献指针(即 FILE 结构体中的位置教悔器)的位置。

重点3

ungetc函数弗成被连结调用。也即是说调用ungetc一次后,再次调用就不会告成,除非接着进行一次读取操作,然后再次调用ungetc函数才会起作用。

重点4

天然字符类型(char类型)骨子上即是int类型,但是弗成期侮,不管是fgetc函数,仍是ungetc函数皆是把字符看成整型参数和整型复返值对待的,天然你不错显式退换或隐示式退换。

重点5

ungetc函数只限于文献输入流,步伐输入流stdin不营救“放回”操作,因此弗成对stdin使用ungetc函数。

ungetc函数的行使场景

预处理或预扫描(文本证实)

当要领需要事前读取一个字符以进行某种判断或预处理,然后证据这个判断决定是否信得过处理这个字符时,不错使用 ungetc。举例,在证实文本文献时,要领可能需要稽察下一个字符以判断接下来的输入阵势,如若阵势不相宜预期,要领可能但愿将字符放回输入流中,以便之后的读取操作约略正确地处理它。

达成自界说的输入流

在创建自界说的输入流或包装器时,可能需要达成近似于 ungetc 的功能,以便在必要时消逝对流的读取操作。

不实处理或规复(数据校验)

如若在读取字符时发生了不实,况且要领但愿回滚到读取之前的景象,不错使用 ungetc。天然这种情况比拟罕有,因为在发生不及时频繁会有更好的不实处理机制,但在某些特定场景中,回滚到之前的读取景象可能是有效的。

交互式输入处理

在编写交互式要领时,举例呐喊行界面或文本裁剪器,要领可能需要证据用户的输入进行复杂的证实和反应。在这些情况下,ungetc 不错用于在证实用户输入时达成更生动的行径。

在某些情况下,重新读取字符可能是为了重新处理它(比如校正之前的不实),或者将其与其他字符组合起来进行证实。在其他情况下,重新读取字符可能仅仅为了投降某种特定的输入条约或阵势条目。总之,是否重新读取回退的字符取决于你的要领逻辑和输入处理的需求。

可是,需要把稳的是,ungetc 的使用应该严慎,因为它可能引入复杂的输入/输出景象科罚问题。过度依赖 ungetc 可能导致代码难以交融和小心。在大多数情况下,更好的作念法是使用缓冲区或临时变量来存储和处理读取到的字符,而不是将它们放回输入流中。

代码实战

(1)代码1:

演示当得胜回退字符后,是回退到缓冲区,因为文献指针莫得改换。下一次读取仍是从缓冲功能区中读取这个字符。不管怎样读取,皆不影响文献本人的位置

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

int main(void){

FILE* fp;

errno_t err;

err = fopen_s(&fp, "foo.txt", "wx+b");

fprintf(fp, "a>b?1:0;");

fflush(fp);

rewind(fp);

int c;

printf("cur pos: %d\n", ftell(fp));

while ((c = fgetc(fp)) != EOF) {

printf("cur pos: %d\n", ftell(fp));

if (isalnum(c)) {

fprintf(stdout,"cur char :%c\n",(char)c);

}

else if(ungetc(c, fp) == EOF){

printf("Fatal error:unget faild!\n ");

return -1;

}

else {

printf("得胜回退:%c\n",c);

}

system("pause");

}

return 0;

}

要领运行的效力如图:

(2)代码2:

这个要领演示了当际遇换行符时,就从内存中回写一个空格字符到输入流,然后再次读取这个空格字符,用来替代换行符,已达到不换行的效力。

#include <stdio.h>

#include <stdlib.h>

int main(void){

FILE* fp;

errno_t err;

err = fopen_s(&fp, "foo.txt", "wx+b");

fprintf(fp, "I love \nChina.\n");

fflush(fp);

rewind(fp);

int c;

while ((c = fgetc(fp)) != EOF) {

if (c == '\n') {

if (ungetc(' ', fp) == EOF) {

printf("Fatal error:unget faild!\n ");

return -1;

}

}

else {

fprintf(stdout, "%c", (char)c);

}

}

return 0;

}

段誉,2024年4月3日,写于合肥。



Powered by kaiyun欧洲杯app(官方)官方网站·IOS/安卓通用版/手机APP下载 @2013-2022 RSS地图 HTML地图