Когда вы используете >>
для извлечения значения из istream
, исходный поток возвращается из выражения.Это означает, что вы можете заменить этот код ...
std::cin >> i1;
std::cin >> i2;
на этот код:
std::cin >> i1 >> i2;
Результатом этого выражения снова будет исходный istream
, и при использовании влогический контекст, возвращает false
, если поток находится в состоянии «сбой».Таким образом, мы можем прочитать два целых числа и проверить, было ли это успешно в одной простой конструкции:
if( std::cin >> i1 >> i2 ) {
std::cout << i1 << "\n" << i2 << "\n";
} else {
Приведенный выше поток войдет в состояние сбоя, когда он пытается прочитать целое число и встречает нецелочисленный символ, такой как вертикальная труба.Чтобы проверить это, нам нужно сначала очистить состояние ошибки, а затем посмотреть, какой символ был в потоке, который вызвал сбой целочисленного чтения.Мы можем сделать это, посмотрев на следующий символ.
} else {
std::cin.clear(); // reset the fail state
if (std::cin.peek() == '|') {
std::cout << "Found end of input marker (|)\n";
} else {
std::cout << "Invalid input!";
}
После определения, был ли это вертикальный канал или нет, целесообразно очистить все символы в потоке до концастрока ввода.
// skip all characters in the stream up to the end of the current line.
std::cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
}
Поместите приведенный выше код в цикл, добавьте оператор break
, когда будет найден вертикальный канал, и вы будете зацикливаться, читая целочисленные значения в парах, пока не введете|
.
while ( !std::cin.eof() ) {
if( std::cin >> i1 >> i2 ) {
std::cout << i1 << "\n" << i2 << "\n";
} else {
std::cin.clear(); // reset the fail state
if (std::cin.peek() == '|') {
std::cout << "Found end of input marker (|)\n";
break;
} else {
std::cout << "Invalid input!";
}
// skip all characters in the stream up to the end of the current line.
std::cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
}
}