c++ - C 中的 cin.ignore() 等价于什么?

标签 c++ c stdin cin stdio

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

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

最佳答案

不,没有。但是让我们看看幕后发生了什么cin.ignore() .我们以llvm libcxx sources为例, 我发现它们比 gcc 的浏览起来更快。

extern istream cin;在 iostream 中,但它在应用程序启动时在 iostream.cpp 中初始化使用静态分配的缓冲区和 __stdoutbuf 对象构造自良好的“旧”FILE * stdin :

_ALIGNAS_TYPE (istream) char cin [sizeof(istream)];
ios_base::Init::Init()  {
    istream* cin_ptr  = ::new(cin)  istream(::new(__cin)  __stdinbuf <char>(stdin) );
    ...

istream::ignore()函数可以在 istraem 中找到.这很简单,首先我们检查用户是否想清除流中的所有字符或只是其中的一些字符 ( if (__n == numeric_limits<streamsize>::max()) )。然后函数调用this->rdbuf()->sbumpc()在一个循环中预定义的计数数量(或者无限,如果 __n 等于 numeric_limits<steramsize::max() )。我们可以找到sbumpc()成为std::basic_streambuf的成员, 来自 cppreference :

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() !先来看看streambuf :

int_type sbumpc() {
    if (__ninp_ == __einp_)
        return uflow();
    return traits_type::to_int_type(*__ninp_++);
}

所以 if (__ninp_ == __einp_)正在 streambuf 中做一些内部缓冲对象,不要打电话 uflow()如果我们的缓冲区中已经有缓冲字符。 __ninp__每次读取后指针都会递增,一定是这样。 uflow()__stdinbuf : public basic_streambuf< .... > 重载, 来自 __std_stream :

template <class _CharT>
typename __stdinbuf<_CharT>::int_type
__stdinbuf<_CharT>::uflow()
{
    return __getchar(true);
}

噗,我们去__getchar并找出 true 是什么参数是。它就在 __std_stream 的正下方.
这是一个长函数,具有主要功能,负责一些缓冲。但是我们可以马上发现这个函数的核心:

template <class _CharT>
typename __stdinbuf<_CharT>::int_type
__stdinbuf<_CharT>::__getchar(bool __consume) {
    ....
        int __c = getc(__file_);
        if (__c == EOF)
            return traits_type::eof();
    ...
}

让我们从头开始:

  • cin是一个 istraem对象并从 __stdinbuf<char>(stdin) 初始化
  • istream::ignore()电话 basic_streambuf::sbumpc()预定义的次数,可能在使用 stdin 初始化的对象上
  • basic_streambuf::sbumpc()处理一些缓冲并调用 basic_streambuf::uflow()如果缓冲区为空。
  • 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;
    }
}

关于c++ - C 中的 cin.ignore() 等价于什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53037333/

相关文章:

c - 使用 C Readline 从文件而不是标准输入中读取一行

c++调试ofstream fail()状态?

c - 如何检查以太网头类型是否为 IEEE 802.1Q?

从 Tibco bw6 调用 C 函数

c - 确定 DST 是否对给定 time_t 的指定时区有效

gcc - gcc从stdin读取gnu readline()的编译错误

c - 一次从 std 获取一个字符的输入 (C)

c++ - gnu slist 执行错误 : lost of file . ../bits/allocator.h: 没有那个文件

c++ - 添加逗号时字符串 * 中的意外 cout <<

C++ 数组大小以及如何管理大数组?