在C中相当于cin.ignore()?

时间:2018-10-29 00:34:09

标签: c++ c stdin cin stdio

我了解C ++流函数是建立在C的stdio库之上的。

在C语言中我要做什么才能获得与cin.ignore(n)相同的结果?
例如,我应该使用stdio函数fseek(stdin, n, 0)还是cin.ignore使用其他方法?

2 个答案:

答案 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_streambufint_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