如何在上次ungetc中获取角色会重新输入文件*

时间:2014-06-20 01:04:42

标签: c

假设我FILE*创建了fopencookie,如果我在ungetc上拨打FILE*会怎样?假设我setvbuf上的FILE*_IONBF以使其无缓冲。看起来fopencookie不支持ungetc的处理程序。

背景是我想在scanf上运行istream,请参阅scanf on an istream object。一个建议是使用fopencookie,我试图将istream包裹为fopencookie的FILE *,问题出来了,我需要确保FILE*没有&# 39; t缓冲任何东西,但是,scanf在解析宽度未知的字段时至少会读取一个字符,例如对于%d,它将继续读取,直到找到空格或行尾。我假设scanf会将字符放回FILE* ungetc,在这种情况下,我需要将此字符放回istream。是否可以知道哪个字符scanf取消了?感谢。

1 个答案:

答案 0 :(得分:1)

fopencookie是一个GNU扩展,据我所知,它不存在于其他C库中。

stdio的GNU libc实现明显比它应该更加毛茸茸因为一个古老的(前EGCS,如果这意味着什么)你试图让FILE个对象直接用作C ++ streambuf个对象 - 没有傻瓜! - 但是你的问题的答案可以在这里找到:https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/genops.c#l722ungetc被命名为_IO_sputbackc的实现是这一古老尝试的剩余遗迹之一)我将引用代码,它很简短:

722 int
723 _IO_sputbackc (fp, c)
724      _IO_FILE *fp;
725      int c;
726 {
727   int result;
728
729   if (fp->_IO_read_ptr > fp->_IO_read_base
730       && (unsigned char)fp->_IO_read_ptr[-1] == (unsigned char)c)
731     {
732       fp->_IO_read_ptr--;
733       result = (unsigned char) c;
734     }
735   else
736     result = _IO_PBACKFAIL (fp, c);
737
738   if (result != EOF)
739     fp->_flags &= ~_IO_EOF_SEEN;
740
741   return result;
742 }

这就是说,如果推回的字符与FILE对象缓冲区中读指针后面的字符相同,它只会将读指针递减一次;否则,调用_IO_PBACKFAIL。在该目录中挖掘更多内容(特别是在libioP.hiofopncook.c中),可以看出_IO_PBACKFAIL FILE创建的fopencookie ungetc这个函数要长得多,我不会引用它,但它的作用是分配一个特殊的“备份缓冲区”并将字符存放在那里。如果需要,此备份缓冲区可以增长以容纳ungetc的任意数量的调用。

因此,您的问题的答案是,无论您连续多次调用FILE(或其他库函数为您执行此操作),您的cookie函数将永远不会被要求做任何事情。它全部由istream内部处理。根据我对你的其他问题的回答,我强烈建议你找到其他方法,但是对于 试图做的事情,我不明白为什么你认为你需要“将此角色也放回{{1}}。”