假设我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
取消了?感谢。
答案 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#l722(ungetc
被命名为_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.h
和iofopncook.c
中),可以看出_IO_PBACKFAIL
FILE
创建的fopencookie
ungetc
这个函数要长得多,我不会引用它,但它的作用是分配一个特殊的“备份缓冲区”并将字符存放在那里。如果需要,此备份缓冲区可以增长以容纳ungetc
的任意数量的调用。
因此,您的问题的答案是,无论您连续多次调用FILE
(或其他库函数为您执行此操作),您的cookie函数将永远不会被要求做任何事情。它全部由istream
内部处理。根据我对你的其他问题的回答,我强烈建议你找到其他方法,但是对于 试图做的事情,我不明白为什么你认为你需要“将此角色也放回{{1}}。”