我了解C ++流函数是建立在C的stdio
库之上的。
在C语言中我要做什么才能获得与cin.ignore(n)
相同的结果?
例如,我应该使用stdio
函数fseek(stdin, n, 0)
还是cin.ignore
使用其他方法?
答案 0 :(得分:2)
不,没有。但是,让我们来看看幕后cin.ignore()
发生了什么。让我们来看看llvm libcxx sources,我发现它们比gcc更快。
extern istream cin;在iostream中,但是它是在iostream.cpp中的应用程序启动时使用静态分配的缓冲区和从良好的“旧” FILE *
stdin
构造的__stdoutbuf对象初始化的:
_ALIGNAS_TYPE (istream) char cin [sizeof(istream)];
ios_base::Init::Init() {
istream* cin_ptr = ::new(cin) istream(::new(__cin) __stdinbuf <char>(stdin) );
...
可以在istraem中找到istream::ignore()
函数。这很简单,首先我们检查用户是否要清除流中的所有字符或仅清除其中的一部分(if (__n == numeric_limits<streamsize>::max())
)。然后,该函数在循环中预定义的计数数量中调用this->rdbuf()->sbumpc()
(如果__n
等于numeric_limits<steramsize::max()
,则循环调用sbumpc()
。我们可以从cppreference中找到std::basic_streambuf
是int_type sbumpc();
Reads one character and advances the input sequence by one character.
If the input sequence read position is not available, returns uflow(). Otherwise returns Traits::to_int_type(*gptr()).
的成员:
this->rdbuf()
因此,我们可以简单地推断出__stdinbuf<char>(stdin)
返回了cin::ignore
的句柄。在__stdinbuf<char>(stdin)::sbumpc()
函数中,对sbumpc()
的调用被执行了很多次,而我们要忽略的字符数也是如此。因此,让我们进入int_type sbumpc() {
if (__ninp_ == __einp_)
return uflow();
return traits_type::to_int_type(*__ninp_++);
}
!首先,让我们看一下streambuf:
if (__ninp_ == __einp_)
因此streambuf
正在uflow()
对象中进行一些内部缓冲,如果缓冲区中已经有缓冲字符,则不要调用__ninp__
。每次读取后uflow()
指针的get就会递增,必须是它。 __stdinbuf : public basic_streambuf< .... >
重载了__std_stream中的template <class _CharT>
typename __stdinbuf<_CharT>::int_type
__stdinbuf<_CharT>::uflow()
{
return __getchar(true);
}
:
__getchar
Puff,让我们转到true
,找出template <class _CharT>
typename __stdinbuf<_CharT>::int_type
__stdinbuf<_CharT>::__getchar(bool __consume) {
....
int __c = getc(__file_);
if (__c == EOF)
return traits_type::eof();
...
}
参数是什么。它位于__std_stream的下方。
这是一个长函数,具有主要功能,需要一些缓冲。但是我们可以立即发现此函数的炉膛:
cin
让我们从头开始:
istraem
是__stdinbuf<char>(stdin)
对象,并从istream::ignore()
初始化basic_streambuf::sbumpc()
调用stdin
预定义次数,可能在使用basic_streambuf::sbumpc()
初始化的对象上调用uflow()
处理一些缓冲区,如果缓冲区为空,则调用basic_streambuf :: basic_streambuf::uflow()
。__stdinbuf::uflos()
被__stdinbuf::__getchar()
重载并调用__sinbuf::__getchar()
getc(__file__)
调用getc(stdin)
,因此可能void stdin_ignore(size_t n, int delim)
{
while (n--) {
const int c = getc(stdin);
if (c == EOF)
break;
if (delim != EOF && delim == c) {
break;
}
}
从流中读取一个字符总结:
T T::operator--(int); // Inside class definition
T operator++(T& a, int); // Outside class definition
答案 1 :(得分:1)
附加地
scanf("%*[^\n]\n"); // Ignores a line
或
scanf("%*s"); // Ignores one string