首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >取消ungetc()的效果:“如何”执行?每次都要重新填充缓冲区吗?

取消ungetc()的效果:“如何”执行?每次都要重新填充缓冲区吗?
EN

Stack Overflow用户
提问于 2013-05-22 07:17:22
回答 2查看 1.6K关注 0票数 0

我该把整件事写在一个清晰的questionLet里吗?我试着:

我知道使用fopen()打开的文件被缓冲为memory.We --使用缓冲区提高效率,ease.During a从文件中读取,文件的内容首先读入缓冲区,然后从buffer.Similarly读取,在对文件的写入中,内容首先写入缓冲区,然后写入文件。

但是,对于rewind()droppingfsetpos()fseek(),之前对ungetc()的调用产生了什么效果呢?你能告诉我是如何完成的吗?我的意思是,考虑到我们打开了一个读取文件,并使用ungetc()将其复制到buffer.Now中,我们更改了buffer.Here中的一些字符,这是我在做了很多努力后仍然无法理解的:

  • 下面是关于ungetc()的说明--“调用流中的查找、fsetpos或倒带将丢弃以前随此函数放入其中的任何字符。”--如何丢弃已放入缓冲区的字符?一种方法是,删除的原始字符被“记住”,而插入的每个新字符都被标识并替换为原始的character.But,似乎inefficient.The的另一种选择是将原始文件的副本加载到缓冲区中,并将文件指针放置在这两种方法的预定position.Which方法中。使用ungetc()丢弃放置字符的fsetpos或倒带
  • 对于文本流,流中未读字符(使用ungetc()的字符)的存在如何影响ftell()的返回值?我的困惑来自于关于ftell()ungetc()的下面一行,这是关于ftell(来源)的链接。

“对于文本流,数值可能没有意义,但可以在以后使用undefined).”将位置恢复到相同的位置(如果有使用ungetc仍待读取的字符放回,则行为为。

  • 集中在上面段落的最后一行,pending of being read与被丢弃的"ungetc()-obtained“字符有什么关系?每次我们使用ungetc()读取放入流中的字符时,是否会在读取之后丢弃该字符?
EN

回答 2

Stack Overflow用户

发布于 2014-01-14 20:24:10

put回退字符的一个很好的心理模型就是它是挂在FILE *对象上的一些额外的小属性。想象一下你有:

代码语言:javascript
复制
typedef struct { 
   /* ... */
   int putback_char;
   /* ... */
} FILE;

假设putback_char被初始化为值EOF,该值表示“不存在putback char",而ungetc只是将字符存储到该成员。

假设每个读取操作都经过getc,而getc执行如下操作:

代码语言:javascript
复制
int getc(FILE *stream)
{
   int ret = stream->putback_char;

   if (ret != EOF) {
     stream->putback_char = EOF;
     if (__is_binary(stream))
        stream->current_position--;
     return ret;
   }

   return __internal_getc(stream); /* __internal_getc doesn't know about putback_char */
}

清除推回的函数只需将EOF分配给putback_char

换句话说,put回退字符(只需要支持一个字符)实际上可以是一个小型缓冲区,它与常规缓冲是分开的。(考虑一下,即使是未缓冲的流也支持ungetc:这样的流必须将字节或字符放在某个位置。)

关于位置指示器,C99标准说:

对于文本流,在成功调用ungetc函数后,将不指定其文件位置指示符的值,直到读取或丢弃所有回推字符为止。对于二进制流,它的文件位置指示符通过对ungetc函数的每一次成功调用而递减;如果在调用之前它的值为零,则在调用之后它是不确定的。7.19.7.11 ungetc函数

因此,您使用的www.cplusplus.com引用是不正确的;当有挂起的字符被ungetc推回时,ftell的行为不是未定义的。对于文本流,值未指定。访问未指定的值不是未定义的行为,因为未指定的值不能是陷阱表示。如果推送发生在零位置,则二进制流存在未定义的行为,因为位置随后变得不确定。不确定意味着它是一个未指定的值,它可能是一个陷阱表示。访问它可以使用错误消息停止程序,或者触发其他行为。

最好是从马嘴里获取编程语言和库规范,而不是从随机的网站。

票数 1
EN

Stack Overflow用户

发布于 2013-05-22 08:55:22

让我们从头开始,

代码语言:javascript
复制
int ungetc(int c, FILE *stream);

函数将c指定的字节(转换为无符号字符)推回流指向的输入流。字符实际上被放回输入流中,减少其内部文件位置,就好像以前的getc操作是undone.This一样,只影响对该流的进一步输入操作,而不影响与其关联的物理文件的内容,而不受对该函数的任何调用的修改。

代码语言:javascript
复制
int fseek(FILE *stream, long offset, int whence);

新的位置,以字节为单位,从文件开始,应通过添加偏移量到指定的位置。指定的点是SEEK_SET文件的开头,SEEK_CUR的文件位置指示符的当前值,或SEEK_END.fseek的文件末尾,或者在设置文件位置之前刷新任何缓冲的输出,或者记住它,以便稍后将其写入文件中的正确位置。

代码语言:javascript
复制
int fsetpos(FILE *stream, const fpos_t *pos);

函数根据pos指向的对象的值设置流的文件位置和状态指示符,该值必须是在同一流上调用fgetpos()时获得的值。

代码语言:javascript
复制
void rewind(FILE *stream);

倒带函数将与流关联的文件指针重新定位到文件的开头。调用倒带类似于

(void) fseek( void,0L,SEEK_SET );

因此,当您看到ungetc()时,向后推字符不会改变文件;只有流的内部缓冲是affected.so,您的第二个注释“另一个选项是将原始文件的副本加载到缓冲区并将文件指针放在预定位置”是正确的。

现在回答您的第二个问题-一个成功的中间调用(由流指向流)对文件定位函数丢弃流的任何回推字符。与流对应的外部存储保持不变。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16685695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档