Я искал этот ответ, и никто, кажется, не знает, как исправить эту ошибку. Я хочу, чтобы ввод был строго int. Если ввод двойной, я хочу отправить ошибку.
int creatLegs = 0;
string trash;
bool validLegs = true;
do
{
cout << "How many legs should the creature have? ";
cin >> creatLegs;
if(cin.fail())
{
cin.clear();
cin >> trash; //sets to string, so that cin.ignore() ignores the whole string.
cin.ignore(); //only ignores one character
validLegs = false;
}
if (creatLegs > 0)
{
validLegs = true;
}
if (!validLegs)
{
cout << "Invalid value, try again.\n";
}
} while (!validLegs);
Кажется, почти работает. Он отправляет ошибку, но только после перехода на следующий цикл. Как я могу это исправить? И почему он по-прежнему показывает сообщение об ошибке, но продолжает отображаться перед его отображением?
Я думаю, что вы должны прочитать данные в виде строки, а затем проверить их тип за символом, чтобы убедиться, что они являются целыми числами — если каждый символ является цифрой, то у нас есть целое число и мы можем его проанализировать.
Проблема с потоками в том, что если вы пытаетесь прочитать целое число, но передается десятичное число, оно читает число до точки. И эта часть является правильным целым числом, поэтому cin.fail()
возвращается false
,
Образец кода:
#include <iostream>
#include <string>
#include <cctype>
#include <cstdlib>
using namespace std;
int main() {
int creatLegs = 0;
bool validLegs = true;
do
{
cout << "How many legs should the creature have? ";
string input;
getline(cin, input);
validLegs = true;
for (string::const_iterator i = input.begin(); validLegs && i != input.end(); ++i) {
if (!isdigit(*i)) {
validLegs = false;
}
}
if (!validLegs)
{
cout << "Invalid value, try again.\n";
} else {
creatLegs = atoi(input.c_str());
}
} while (!validLegs);
cout << creatLegs << endl;
}
Это, конечно, не идеальное решение. Если есть начальные или конечные пробелы (или любые другие символы, такие как +
или же -
), программа потерпит неудачу. Но вы всегда можете добавить некоторый код для обработки этих ситуаций, если вам нужно.
Вход может быть чем-то другим, чем представление целого числа или числа с плавающей запятой.
Помните, что числа не являются их представлением (ями): 9
(десятичный), 017
(восьмеричное, а-ля C), 0b1001
(бинарный, а-ля Ocaml), IX
(Римская запись), 8+1
(арифметическое выражение), neuf
(Французский) все представления одного и того же числа девять.
Таким образом, вы должны решить, если вы принимаете вход как 9 x
, или же 9
(с несколькими пробелами после цифры), … В более общем случае вы должны определить, какие допустимые входные данные (и если ввод заканчивается в конце строки или нет, если должны быть приняты пробелы или знаки пунктуации и т. д …) ,
Вы можете прочитать всю строку (например, с станд :: GetLine) и использовать, например, sscanf
(где %n
полезен управляющий формат, а также счетчик элементов, возвращаемый sscanf
) или же станд :: КВП (где вы используете указатель конца), чтобы разобрать его
Заметьте также, что формулировка вашего вопроса («Различение между int и double») неверна. Там нет ни одного «int
или же double
«введите в C ++ (но int
является скалярным типом, и double
является скалярным типом в C ++, и вы можете определить class
с помеченный союз провести любой из них). AFAIU, если вы объявите int x;
затем используйте std::cin >> x;
с пользовательским вводом 12.64
точка и цифры 64
после того, как он не будет проанализирован и x
станет 12.
int creatLegs = 0;
do
{
cout << "How many legs should the creature have? ";
cin >> creatLegs; // trying to get integer
if(!cin.fail()) // if cin.fail == false, then we got an int and leave loop
break;
cout << "Invalid value, try again.\n"; // else show err msg and try once more
cin.clear();
} while (1);
На этот вопрос уже есть принятый ответ, однако я внесу решение, которое обрабатывает все целые числа, даже те, которые выражаются как числа с плавающей запятой (без дробной части), и отклоняет ввод, который содержит что-либо, кроме пробелов, следующих за число.
Примеры принятых значений, все они представляют число 4:
4 4. 4.0 +4 004.0 400e-2
Примеры отклоненных значений:
3.999999 4.000001 40e-1x 4,
#include <iostream>
#include <sstream>
#include <cctype>
#include <string>
using namespace std;
bool get_int( const string & input, int & i ) {
stringstream ss(input);
double d;
bool isValid = ss >> d;
if (isValid) {
char c;
while( isValid && ss >> c ) isValid = isspace(c);
if (isValid) {
i = static_cast<int>(d);
isValid = (d == static_cast<double>(i));
}
}
return isValid;
}
int main( int argc, char *argv[] )
{
int creatLegs = 0;
bool validLegs = false;
do
{
string line;
do {
cout << "How many legs should the creature have? ";
} while (not getline (cin,line));
validLegs = get_int( line, creatLegs );
if (creatLegs <= 0)
{
validLegs = false;
}
if (not validLegs)
{
cout << "Invalid value, try again." << endl;
}
} while (not validLegs);
cout << "Got legs! (" << creatLegs << ")" << endl;
return 0;
}
Если вы хотите строго целые числа (без десятичной точки и без научных обозначений), используйте это проще get_int функция:
bool get_int( const string & input, int & i ) {
stringstream ss(input);
bool isValid = ss >> i;
if (isValid) {
char c;
while(isValid && ss >> c) isValid = isspace(c);
}
return isValid;
}