Ответ 1
При чтении из std:: cin предпочтительнее не использовать оператор извлечения потока >>
, поскольку это может иметь всевозможные неприятные побочные эффекты. Например, если у вас есть этот код:
std::string name;
std::cin >> name;
И я введу John Doe
, тогда строка, которая будет читаться из cin
, просто сохранит значение John
, оставив Doe
позади, чтобы прочитать некоторую будущую операцию чтения. Точно так же, если бы я написал:
int myInteger;
std::cin >> myInteger;
И затем введите John Doe
, затем cin
войдет в состояние ошибки и откажется выполнять какие-либо будущие операции чтения, пока вы явно не очистите его состояние ошибки и не очистите символы, вызвавшие ошибку.
Лучший способ сделать ввод данных - использовать std:: getline, чтобы читать символы с клавиатуры, пока пользователь не наткнется на вход. Например:
std::string name;
getline(std::cin, name); // getline doesn't need the std:: prefix here because C++ has ADL.
ADL означает зависящий от аргумента поиск. Теперь, если я введу John Doe
, значение name
будет John Doe
, и в cin
не останется никаких данных. Кроме того, это также позволяет вам проверить, только что нажал пользователь:
std::string name;
getline(std::cin, name);
if (name.empty()) {
/* ... nothing entered ... */
}
Недостатком этого подхода является то, что если вы хотите читать в форматированной строке данных, int
или double
, вам придется проанализировать представление из строки. Я лично считаю, что это того стоит, потому что это дает вам более тонкий контроль над тем, что делать, если пользователь вводит что-то недействительное и "охраняет" cin
из когда-либо входящего в состояние отказа.
Я преподаю курс программирования на С++ и некоторые лекционные заметки о библиотеке потоков, в которой содержится подробная информация о том, как читать отформатированные данные из cin
безопасным способом (в основном в конце главы). Я не уверен, насколько это полезно, но если это полезно, я подумал, что отправлю ссылку.
Надеюсь, это поможет!