Нет, нет. Но давайте посмотрим, что происходит за занавесом под названием cin.ignore()
. Давайте возьмем llvm libcxx , я нахожу их быстрее, чем 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__
указатель get увеличивается после каждого чтения, это должно быть. 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;
}
}