• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Cin Принимает Только Цифры

  • Автор темы Negent
  • Дата начала
N

Negent

Доброго времени суток!
Написал программу, которая считывает и выводит элементы массива... Всё просто, но на самом деле, мне бы чуть больше понимания, как работает кусок кода (программа рабочая).
Код:
//Эта программа добивается ввода чисел, вместо всякой ерунды
#include <iostream>
#include "stdafx.h"
using namespace std;

void main ()
{
int Ar[5];
int value;
for (int i=0; i<5; i++)
{
cout<<"Ar["<<i+1<<"]: ";
cin>>value;
while (!cin)
{
cout<<"Enter again A["<<i+1<<"]: ";
cin.clear ();
while (cin.get ()!= '\n') continue;
cin>>value;
}
Ar = value;
}
cout<<"Exit!"<<endl;
for (int i=0; i<5; i++)
cout<<"A["<<i+1<<"]: "<<Ar<<endl;
system ("pause");
}


А именно, вот этот кусок:
for (int i=0; i<5; i++)
{
cout<<"Ar["<<i+1<<"]: ";
cin>>value;
while (!cin)
{
cin.clear ();
while (cin.get ()!= '\n') continue;
cout<<"Enter again A["<<i+1<<"]: ";
cin>>value;
}
Ar = value;
}


Проверьте пожалуйста, ход рассуждений (только это, переписывать ничего не надо в коде!):
1. Ввод значения во временную переменную "value".
2. Если введённое значение не подходит, то в очереди потока в cin, выставляется флаг, имеющий значение "ложь", что даёт запуск цикла "while". (истина = не-ложь)
3. Цикл "while (!cin)" операторами в теле цикла: cin.clear() очищает очередь символов , а while (cin.get()) выполняет сброс символа новой строки столько раз, пока они там есть. Continue выполняет новую и новую итерацию, пока там ещё есть символы новой строки. Сам cin.clear () не может выполнить очистку на символы новой строки.
4. Производится считывание временной переменной "value", если оно истинно, т.е. введено корректное значение (число), то флаг в условии цикла while (!cin) равен "истина".
5. Число присваивается элементу массива. При наличии корректного ввода, происходит выполнение цикла for (), без циклов while()
 
E

Evgeniy

1. Переменная value не является временной, она доступна на все время выполнения программы. Но в целом да, мы с помощью неё действительно вводим значения.
2. Да, верно. Если объект cin возвращает значение 0(false), то запускается цикл с условием пока cin не вернет 1, пока cin не истина.
3. cin.clear() сбрасывает значение объекта cin с 0 в 1. А вот while (cin.get() != '\n')... Я пытался понять каким фигом это работает, но... continue тупо перебрасывает цикл к проверке условия, но это и понятно. Теоретически этот "цикл"...
Понятно, как работает (cin.get() != '\n'). При вызове cin.get() считывает один символ с входного потока. Итак, как же работает это условие. Представим такую ситуацию: я ввожу на поток символы **3, что будет делать while (cin.get() != '\n')? Он считывает *, заходит в цикл (ибо условие выполняется) и оператор continue тупо перебрасывает цикл в проверке условия. Continue тут является неким итератором цикла. Потом cin.get() считывает второй символ (*) и делает все тоже самое, что я описал выше. Потом он считывает третий символ (3) и опять таки переходит к проверке условия. Потом, что бы проверить условие cin.get() != '\n' считывает еще один символ, тем самым оканчивая поток ввода. Условие цикла становится ложным и цикл завершается. В общем, этот цикл работает количество раз равное: количество введенных символов +1 (один уходит на '\n'). Для лучшего понимания погуглите "cin.get() != '\n'" и первая ссылка - это то, что вам нужно, там все доходчиво расписано. В целом, вы все поняли правильно.
4. Угу. Вызываем cin и снова переходим к нашему циклу while (!cin). Если cin в true, то цикл завершается, значение записывается в массив по индексу i и мы переходим к началу цикла for.
5. Ну, можно и так сказать, конечно, но все же... После того, как мы перешли к циклу for мы снова вызываем cin, вводим значение и переходим к циклу while(!cin). Если мы ввели корректные значения, то в цикл while(!cin) мы не заходим. К чему я веду: к while мы в любом случае приходим, хотим мы того или нет, а вот выполняем ли мы условия цикла while (заходим ли мы в него) зависит от того, что мы передали на поток ввода)

Если что - то осталось не понятно, то задайте вопрос в этой теме)
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!