Обновление. Теперь вы можете экспортировать отчеты аналитики в виде CSV из консоли Firebase, щелкнув опцию «Загрузить CSV» в меню переполнения..
. Тем временем вы действительно должны дать BigQuery другой смотреть. цена очень разумна и существует свободный уровень запросов 1 ТБ / мес.
Стив Ганем
Менеджер продуктов, Firebase Analytics
Причина, по которой программа переходит в бесконечный цикл, связана с тем, что флаг неудачного ввода std::cin
установлен из-за сбоя ввода. Необходимо сделать это, чтобы очистить этот флаг и отбросить плохой вход из входного буфера.
//executes loop if the input fails (e.g., no characters were read)
while (std::cout << "Enter a number" && !(std::cin >> num)) {
std::cin.clear(); //clear bad input flag
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discard input
std::cout << "Invalid input; please re-enter.\n";
}
См. C ++ FAQ для этого и другие примеры, включая добавление минимальный и / или максимальный в условие.
Другим способом было бы получить ввод как строку и преобразовать его в целое число с std::stoi
или другим методом, который позволяет проверять преобразование.
Ответ на главный проголосовавший ответ очень хорошо удовлетворяет решению.
В дополнение к этому ответу это может помочь визуализировать то, что происходит немного лучше:
int main()
int input = 1;//set to 1 for illustrative purposes
bool cinState = false;
string test = "\0";
while(input != -1){//enter -1 to exit
cout << "Please input (a) character(s): ";//input a character here as a test
cin >> input; //attempting to input a character to an int variable will cause cin to fail
cout << "input: " << input << endl;//input has changed from 1 to 0
cinState = cin;//cin is in bad state, returns false
cout << "cinState: " << cinState << endl;
cin.clear();//bad state flag cleared
cinState = cin;//cin now returns true and will input to a variable
cout << "cinState: " << cinState << endl;
cout << "Please enter character(s): ";
cin >> test;//remaining text in buffer is dumped here. cin will not pause if there is any text left in the buffer.
cout << "test: " << test << endl;
}
return 0;
}
Сбрасывание текста в буфере переменной не особенно полезен, однако помогает визуализировать, почему cin.ignore()
необходим.
Я также отметил изменение входной переменной, потому что, если вы используете переменную ввода в вашем состоянии для цикла while
или оператор switch, он может зайти в тупик или выполнить условие, которого вы не ожидали, что может быть более запутанным для отладки.
Проверьте вход, чтобы узнать, ожидает ли ваша программа. Если это не так, предупредите пользователя о том, что введенный им ввод является неприемлемым.
Вы можете проверить это через значение ASCII, если значение ascii s между 65 t0 90 или 97 to 122 будет символом.
cin.ignore (1000, '\n')
игнорирует / отбрасывает символы во входном буфере до тех пор, пока не будет отброшена ни одна из 1000, или столбец новой строки, в зависимости от того, что наступит раньше. Это хороший способ избавиться от линии. В парашютном примере вы увидите максимальный размер потока вместо 1000, чтобы учесть длину максимальной длины. Я используюcin.sync()
, потому что, когда я это делаю, я хочу быть на равных с пользователем (еще не прочитал следующую строку), поэтому я отбрасываю все. Наконец,cin
имеетoperator void *
, поэтому он cann преобразуется в bool. – chris 27 April 2012 в 12:48cin >> num
терпит неудачу, если пользователь набирает, скажем 'a', когда он ожидал int. Он предоставляет оператор преобразования, чтобы он неявно преобразовывался вvoid *
. Еслиcin
находится в плохом состоянии, он вернетNULL
. Если нет, он вернет объект. Затем это можно сделать и преобразовать в bool: true, если не NULL, false, если NULL. Затем цикл может использовать это для оценки выражения bool, в котором он нуждается. – chris 27 April 2012 в 13:15