Cin ignore c что это

от admin

Русские Блоги

cin.sync () используется для очистки потока данных в области кэша.
Если идентификатор не изменился, его нельзя ввести, даже если поток данных очищен. Таким образом, эти два должны использоваться вместе.

Мы определяем переменную, которая будет введена как целое число, но если мы введем английские буквы или китайские символы, произойдет ошибка. В cin есть метод для обнаружения этой ошибки, который называется cin.rdstate (); когда cin.rdstate () При возврате 0 (то есть ios :: goodbit) ошибки нет, и вы можете продолжить ввод или работу. Если вы вернете 4, произойдет нефатальная ошибка, то есть ios :: failbit, вы не сможете продолжать вводить или работать. И cin.clear может контролировать нас. Идентификация этой проблемы в cin. Язык следующий: cin.clear (идентификатор); идентификационный символ:

Goodbit без ошибок
Eofbit достиг конца файла
нефитальная ошибка ввода / вывода при сбое, исправимая
badbit Фатальная ошибка ввода / вывода, не может быть исправлена. Если она находится в классе ввода / вывода, вам необходимо добавить ios :: identifier
С помощью cin.clear мы можем подтвердить его внутренний идентификатор и повторно ввести его, если он введен неправильно. В сочетании с методом реального очищения потока данных cin.sync () см. следующий пример:

Приведенный выше параметр по умолчанию для cin.clear () равен 0, то есть без ошибок, при нормальной работе. Когда мы вводим английскую букву ‘k’, ее статусный идентификатор изменяется на сбой, то есть ошибка, используется cout для вывода информации пользователю, а затем используется cin .clear Позволяет изменить флаг ошибки обратно на 0, чтобы мы могли продолжить ввод, а затем очистить данные потока для продолжения ввода. Если у нас нет cin.clear, мы войдем в бесконечный цикл. Процесс состоит в том, что мы вводим английские буквы и их флаг состояния. Это сбой. Когда выполняется условное суждение, оно всегда возвращается к неправильному условному представлению, и мы больше не можем вводить его, потому что неправильный указатель закрывает cin, поэтому он входит в бесконечный цикл.

2. cin.ignore()

Метод cin.ignore (a, ch) предназначен для извлечения символов из входного потока (cin). Извлеченные символы игнорируются и не используются. Каждый раз, когда символ отбрасывается, он подсчитывает и сравнивает символы: если число достигает a или символ, который отбрасывается, является ch, выполнение функции cin.ignore () прекращается, в противном случае он продолжает ждать. Обычной функцией является очистка содержимого буфера ввода, заканчивающегося возвратом каретки, что исключает влияние предыдущего ввода на следующий ввод. Например, это может быть использовано: cin.ignore (1024, ‘\ n’), обычно первый параметр устанавливается достаточно большим, так что на самом деле всегда работает только второй параметр ‘\ n’, так что это предложение ставится Все символы перед возвратом каретки (включая возврат каретки) удаляются из входного буфера (потока).

Если cin.ignore () не существует, вы можете ввести 3 числа одновременно, разделенных пробелами. , Но очень неприглядно. , Это то, что мы хотим.

Если cin.ignore () не задан параметр, параметром по умолчанию является cin.ignore (1, EOF), то есть 1 символ перед EOF очищается, и один символ очищается без обнаружения EOF, а затем заканчивается, что приведет к ошибке Результат, потому что EOF — это конец файла логотипа.

Если вы введете bcdabcd в адрес, то в это время в потоке останется bcd \ n, а cin.ignore (), в это время съедено b, что оставит оставшийся cd \ n в потоке непосредственно в cin.getline ( str3,30); должен быть символ \ n, поэтому getline возвращается прямо сюда.

3 Сравнение cin.sync () и cin.ignor ()

Эффект sync () заключается в очистке входного буфера. Возвращает 0 при успехе, badbit устанавливается при сбое, а функция возвращает -1.
Кроме того, для входного потока, связанного с выходом, вызов sync () также очистит выходной буфер.

Но поскольку программа не всегда знает ход выполнения внешнего ввода во время выполнения программы, трудно контролировать, очищено ли содержимое буфера ввода. Часто мы можем просто отказаться от части, а не от всего входного буфера. Например, очистка текущей строки или очистка символов новой строки в конце строки. Но если в буфере уже есть следующая строка, эта часть может быть тем, что мы хотим сохранить. В настоящее время лучше не использовать sync (). Попробуйте вместо этого использовать функцию игнорирования.
cin.ignore (numeric_limits :: max (), ’/ n’); // очистить текущую строку
cin.ignore (numeric_limits :: max ()); // Очистить все в cin

Не пугайтесь длинного имени, numeric_limits :: max () — это просто максимальное значение, используемое потоком, определенным заголовочным файлом climits, вы также можете заменить его на достаточно большое целое число.

Использование ignore, очевидно, более точно контролирует буфер, чем sync ().

7.16 — std::cin and handling invalid input

Most programs that have a user interface of some kind need to handle user input. In the programs that you have been writing, you have been using std::cin to ask the user to enter text input. Because text input is so free-form (the user can enter anything), it’s very easy for the user to enter input that is not expected.

As you write programs, you should always consider how users will (unintentionally or otherwise) misuse your programs. A well-written program will anticipate how users will misuse it, and either handle those cases gracefully or prevent them from happening in the first place (if possible). A program that handles error cases well is said to be robust.

In this lesson, we’ll take a look specifically at ways the user can enter invalid text input via std::cin, and show you some different ways to handle those cases.

std::cin, buffers, and extraction

In order to discuss how std::cin and operator>> can fail, it first helps to know a little bit about how they work.

When we use operator>> to get user input and put it into a variable, this is called an “extraction”. The >> operator is accordingly called the extraction operator when used in this context.

When the user enters input in response to an extraction operation, that data is placed in a buffer inside of std::cin. A buffer (also called a data buffer) is simply a piece of memory set aside for storing data temporarily while it’s moved from one place to another. In this case, the buffer is used to hold user input while it’s waiting to be extracted to variables.

  • If there is data already in the input buffer, that data is used for extraction.
  • If the input buffer contains no data, the user is asked to input data for extraction (this is the case most of the time). When the user hits enter, a ‘\n’ character will be placed in the input buffer.
  • operator>> extracts as much data from the input buffer as it can into the variable (ignoring any leading whitespace characters, such as spaces, tabs, or ‘\n’).
  • Any data that can not be extracted is left in the input buffer for the next extraction.

Extraction succeeds if at least one character is extracted from the input buffer. Any unextracted input is left in the input buffer for future extractions. For example:

If the user enters “5a”, 5 will be extracted, converted to an integer, and assigned to variable x. “a\n” will be left in the input buffer for the next extraction.

Extraction fails if the input data does not match the type of the variable being extracted to. For example:

If the user were to enter ‘b’, extraction would fail because ‘b’ can not be extracted to an integer variable.

The process of checking whether user input conforms to what the program is expecting is called input validation.

There are three basic ways to do input validation:

  1. Prevent the user from typing invalid input in the first place.

Post-entry (after the user types):

  1. Let the user enter whatever they want into a string, then validate whether the string is correct, and if so, convert the string to the final variable format.
  2. Let the user enter whatever they want, let std::cin and operator>> try to extract it, and handle the error cases.

Some graphical user interfaces and advanced text interfaces will let you validate input as the user enters it (character by character). Generally speaking, the programmer provides a validation function that accepts the input the user has entered so far, and returns true if the input is valid, and false otherwise. This function is called every time the user presses a key. If the validation function returns true, the key the user just pressed is accepted. If the validation function returns false, the character the user just input is discarded (and not shown on the screen). Using this method, you can ensure that any input the user enters is guaranteed to be valid, because any invalid keystrokes are discovered and discarded immediately. Unfortunately, std::cin does not support this style of validation.

Since strings do not have any restrictions on what characters can be entered, extraction is guaranteed to succeed (though remember that std::cin stops extracting at the first non-leading whitespace character). Once a string is entered, the program can then parse the string to see if it is valid or not. However, parsing strings and converting string input to other types (e.g. numbers) can be challenging, so this is only done in rare cases.

Most often, we let std::cin and the extraction operator do the hard work. Under this method, we let the user enter whatever they want, have std::cin and operator>> try to extract it, and deal with the fallout if it fails. This is the easiest method, and the one we’ll talk more about below.

A sample program

Consider the following calculator program that has no error handling:

This simple program asks the user to enter two numbers and a mathematical operator.

Now, consider where invalid user input might break this program.

First, we ask the user to enter some numbers. What if they enter something other than a number (e.g. ‘q’)? In this case, extraction will fail.

Second, we ask the user to enter one of four possible symbols. What if they enter a character other than one of the symbols we’re expecting? We’ll be able to extract the input, but we don’t currently handle what happens afterward.

Third, what if we ask the user to enter a symbol and they enter a string like «*q hello» . Although we can extract the ‘*’ character we need, there’s additional input left in the buffer that could cause problems down the road.

Types of invalid text input

  • Input extraction succeeds but the input is meaningless to the program (e.g. entering ‘k’ as your mathematical operator).
  • Input extraction succeeds but the user enters additional input (e.g. entering ‘*q hello’ as your mathematical operator).
  • Input extraction fails (e.g. trying to enter ‘q’ into a numeric input).
  • Input extraction succeeds but the user overflows a numeric value.
Читать:
Что такое ошибка opengl

Thus, to make our programs robust, whenever we ask the user for input, we ideally should determine whether each of the above can possibly occur, and if so, write code to handle those cases.

Let’s dig into each of these cases, and how to handle them using std::cin.

Error case 1: Extraction succeeds but input is meaningless

This is the simplest case. Consider the following execution of the above program:

In this case, we asked the user to enter one of four symbols, but they entered ‘k’ instead. ‘k’ is a valid character, so std::cin happily extracts it to variable op, and this gets returned to main. But our program wasn’t expecting this to happen, so it doesn’t properly deal with this case (and thus never outputs anything).

  1. Check whether the user’s input was what you were expecting.
  2. If so, return the value to the caller.
  3. If not, tell the user something went wrong and have them try again.

Here’s an updated getOperator() function that does input validation.

As you can see, we’re using a while loop to continuously loop until the user provides valid input. If they don’t, we ask them to try again until they either give us valid input, shutdown the program, or destroy their computer.

Error case 2: Extraction succeeds but with extraneous input

Consider the following execution of the above program:

What do you think happens next?

The program prints the right answer, but the formatting is all messed up. Let’s take a closer look at why.

When the user enters 5*7 as input, that input goes into the buffer. Then operator>> extracts the 5 to variable x, leaving *7\n in the buffer. Next, the program prints “Enter one of the following: +, -, *, or /:”. However, when the extraction operator was called, it sees *7\n waiting in the buffer to be extracted, so it uses that instead of asking the user for more input. Consequently, it extracts the ‘*’ character, leaving 7\n in the buffer.

After asking the user to enter another double value, the 7 in the buffer gets extracted without asking the user. Since the user never had an opportunity to enter additional data and hit enter (causing a newline), the output prompts all run together on the same line.

Although the above program works, the execution is messy. It would be better if any extraneous characters entered were simply ignored. Fortunately, it’s easy to ignore characters:

This call would remove up to 100 characters, but if the user entered more than 100 characters we’ll get messy output again. To ignore all characters up to the next ‘\n’, we can pass std::numeric_limits<std::streamsize>::max() to std::cin.ignore() . std::numeric_limits<std::streamsize>::max() returns the largest value that can be stored in a variable of type std::streamsize . Passing this value to std::cin.ignore() causes it to disable the count check.

To ignore everything up to and including the next ‘\n’ character, we call

Because this line is quite long for what it does, it’s handy to wrap it in a function which can be called in place of std::cin.ignore() .

Since the last character the user entered must be a ‘\n’, we can tell std::cin to ignore buffered characters until it finds a newline character (which is removed as well).

Let’s update our getDouble() function to ignore any extraneous input:

Now our program will work as expected, even if we enter “5*7” for the first input — the 5 will be extracted, and the rest of the characters will be removed from the input buffer. Since the input buffer is now empty, the user will be properly asked for input the next time an extraction operation is performed!

Some lessons still pass 32767 to std::cin.ignore() . This is a magic number with no special meaning to std::cin.ignore() and should be avoided. If you see such an occurrence, feel free to point it out.

Error case 3: Extraction fails

Now consider the following execution of our updated calculator program:

You shouldn’t be surprised that the program doesn’t perform as expected, but how it fails is interesting:

and that last line keeps printing until the program is closed.

This looks pretty similar to the extraneous input case, but it’s a little different. Let’s take a closer look.

When the user enters ‘a’, that character is placed in the buffer. Then operator>> tries to extract ‘a’ to variable x, which is of type double. Since ‘a’ can’t be converted to a double, operator>> can’t do the extraction. Two things happen at this point: ‘a’ is left in the buffer, and std::cin goes into “failure mode”.

Once in “failure mode”, future requests for input extraction will silently fail. Thus in our calculator program, the output prompts still print, but any requests for further extraction are ignored. This means that instead waiting for us to enter an operation, the input prompt is skipped, and we get stuck in an infinite loop because there is no way to reach one of the valid cases.

Fortunately, we can detect whether an extraction has failed:

Because std::cin has a Boolean conversion indicating whether the last input succeeded, it’s more idiomatic to write the above as following:

Let’s integrate that into our getDouble() function:

A failed extraction due to invalid input will cause the variable to be zero-initialized. Zero initialization means the variable is set to 0, 0.0, “”, or whatever value 0 converts to for that type.

Error case 4: Extraction succeeds but the user overflows a numeric value

Consider the following simple example:

What happens if the user enters a number that is too large (e.g. 40000)?

In the above case, std::cin goes immediately into “failure mode”, but also assigns the closest in-range value to the variable. Consequently, x is left with the assigned value of 32767. Additional inputs are skipped, leaving y with the initialized value of 0. We can handle this kind of error in the same way as a failed extraction.

Putting it all together

Here’s our example calculator, updated with a few additional bits of error checking:

  • Could extraction fail?
  • Could the user enter more input than expected?
  • Could the user enter meaningless input?
  • Could the user overflow an input?

You can use if statements and boolean logic to test whether input is expected and meaningful.

The following code will clear any extraneous input:

The following code will test for and fix failed extractions or overflow:

Finally, use loops to ask the user to re-enter input if the original input was invalid.

Input validation is important and useful, but it also tends to make examples more complicated and harder to follow. Accordingly, in future lessons, we will generally not do any kind of input validation unless it’s relevant to something we’re trying to teach.

std:: istream::ignore

Extracts characters from the input sequence and discards them, until either n characters have been extracted, or one compares equal to delim .

The function also stops extracting characters if the end-of-file is reached. If this is reached prematurely (before either extracting n characters or finding delim ), the function sets the eofbit flag.

Internally, the function accesses the input sequence by first constructing a sentry object (with noskipws set to true ). Then (if good ), it extracts characters from its associated stream buffer object as if calling its member functions sbumpc or sgetc , and finally destroys the sentry object before returning.

Parameters

Return Value

The istream object ( *this ).

Errors are signaled by modifying the internal state flags:

flag error
eofbit The function stopped extracting characters because the input sequence has no more characters available (end-of-file reached).
failbit The construction of sentry failed (such as when the stream state was not good before the call).
badbit Error on stream (such as when this function catches an exception thrown by an internal operation).
When set, the integrity of the stream may have been affected.

Multiple flags may be set by a single operation.

If the operation sets an internal state flag that was registered with member exceptions , the function throws an exception of member type failure .

How to use cin.ignore in C++ to clear input buffer

Hello, Coders! In this section, we will discuss and learn about the cin.ignore () function and its use in C++.

So, let’s cover the below topics briefly:

  • Buffer
  • cin.ignore() function

Use of Buffer in programming

  • A buffer is a temporary storage device or some block of memory that is used to store the input and output values for the program. All the standard output and input devices contain an input and output buffer, respectively.
  • When we give the input from the keyboard it doesn’t send the values to the program directly, instead, it stores them in the buffer and then is allotted to the program.

cin.ignore() in C++

  • The ignore() function is used to ignore or discard the number of characters in the stream up to the given delimiter.
  • It is a member function of std::basic_istream and inherited from input stream classes.
  • It takes the number of characters and the delimiter character as arguments.

Syntax:

In some cases, we may need to delete the unwanted buffer, so that when a new value is taken next time, it stores the value in the appropriate buffer, not in the previous variable buffer.

Let’s understand the scenario by a program:

Output:

In this example, we didn’t get the desired output from the program. We have taken two cin input streams, one for the num and the other from the string name , but only the num value is taken. It ignored the getline() without taking any input value. In this case, the value goes to the num variable buffer, as a result, we didn’t get the string value.

Here, we can use the cin.ignore() to resolve the problem:

Output:

Note: numeric_limits<streamsize>::max() is taken as an argument for the ignore() function to force special cases and disable the number of characters.

You can understand with the below examples as well,

cin.ignore ( numeric_limits::max(),’\n’) removes everything in the input stream including the newline.

Program to show how buffer affects programming in C++

The output is not what we expected because of the input buffer as the “\n” goes in the buffer and gets read as the next input.

Похожие статьи