2009-04-24 3 views
8

Я новичок здесь. Я нашел этот сайт в Google.C++ проверить, является ли число int/float

#include <iostream> 

using namespace std; 

void main() { 

    // Declaration of Variable 
    float num1=0.0,num2=0.0; 

    // Getting information from users for number 1 
    cout << "Please enter x-axis coordinate location : "; 
    cin >> num1; 

    // Getting information from users for number 2 
    cout << "Please enter y-axis coordinate location : "; 
    cin >> num2; 

    cout << "You enter number 1 : " << num1 << " and number 2 : " << num2 <<endl; 

Мне нужно что-то вроде, когда пользователи вводят алфавитные символы, оно будет показывать ошибку, вы должны ввести цифры.

Любая помощь очень ценится

+0

использовать стандартные функции: петли через все символы в значении и проверить с isdigit() смотрите здесь для примера http://www.cplusplus.com/reference/clibrary/cctype/isdigit/ –

ответ

6

использовать что-то вроде

if (static_cast<int>(num1) == num1) { 
    // int value 
} 
else { 
    // non-integer value 
} 
2

Входной сигнал будет отбрасывать, чтобы соответствовать переменной вы хранящий с CIN. Поскольку вы используете cin для num1 и num2 (которые являются float), независимо от того, какой номер вводит пользователь (до некоторой степени), он будет плавать.

4

Если вы хотите проверить ввод для integer/float /, вы не должны использовать cin в float. Вместо этого прочитайте его в строку, и вы можете проверить, действителен ли вход.

Если CIN читает недействительный номер будет идти в несостоявшееся государство, которое может быть проверено с, если (cin.fail())

Однако это легче читать ввод в строку, а затем преобразовать после этого вводится целое число или число с плавающей запятой.

isdigit (c) должен быть вызван символом, а не целым числом. Например isdigit ('1') (обратите внимание на кавычки).

вы можете использовать strtol, чтобы попытаться преобразовать строку в целое число. В зависимости от результата вы можете попытаться преобразовать в плавающую точку.

+0

'strotol' не соответствует стандартам. Кроме того, я не понимаю, почему чтение в строку, а затем использование' isdigit' или ручного анализа должно быть проще, чем проверка состояния отказа stream. –

+2

@ Konrad Rudolph: Во-первых, с каких пор 'strtol' стал несовместимым? Во-вторых, спецификация отказа/успеха потока часто отличается от желаемого пользователем. Например, поток позволит' 123abc' вход, сто pping на 'a', тогда как пользователь может отказаться от такого ввода. Вот почему чтение строки, а затем «ручной» анализ с помощью 'strtol' работает лучше всего в большинстве случаев. – AnT

+0

@AndreyT Не знаю, почему я думал, что 'strtol' не является стандартным. Но о вашей жалобе с потоками, решение этой проблемы было бы также проверить «eof». Я все еще не понимаю, почему косвенность через строку (и, возможно, 'strtol') должна быть« проще ». –

3

Хотя другие уже ответили на этот вопрос, я просто хотел бы указать, для чего действительно используется isdigit. Он сообщает вам, соответствует ли данный символ числу или нет.

В принципе, определение isdigit может быть:

int isdigit (int c) 
{ 
    if (c >= '0' && c <='9') 
     return 1; 
    else 
     return 0; 
} 

Затем, если у вас есть строка "asdf1234", вы можете проверить каждый символ по отдельности, чтобы проверить, если это цифра/номер:

char *test = "asdf1234"; 
int i; 

for (i = 0; i < strlen (test); i++) 
{ 
    if (isdigit (test[i])) 
     fprintf (stdout, "test[%d] is a digit!\n", i); 
} 
+0

Да. Вы также должны принять минус, плюс, тысячи и десятичные разделители, используемые в текущей локали (не только 0-9). – Jem

+0

Должно, вероятно, также принимать начальные и конечные пробелы. Те не передают «isdigit», но могут быть действительными частями ввода (хотя их следует убрать как можно раньше). – abelenky

+0

@Jem: определение isdigit в ANSI C не проверяет плюсы, минусы, группировки или десятичные разделители. isdigit возвращает ненулевое значение, только если параметр является цифрой, и ничего больше. Проверьте его на своей системе и посмотрите. Правильный анализатор чисел будет использовать функцию более всеобъемлющую, чем isdigit, но цель моего ответа состояла в том, чтобы объяснить isdigit. – dreamlax

1

Всегда прочитать номер в строку и проверить то же самое, как показано ниже: -

template <class out_type, class in_type> 
out_type convert(in_type const& t) 
{ 
    std::stringstream stream; 
    stream << t; // insert value to stream 
    // store conversion’s result here 
    out_type result; 
    stream >> result; // write value to result 
    // if there is a failure in conversion the stream will not be empty 
    // this is checked by testing the eof bit 
    if (! stream.eof()) // there can be overflow also 
    { // a max value in case of conversion error 
    result = std::numeric_limits<out_type>::max(); 
    } 
    return result; 
} 

Он используется как

int iValue = convert<int>(strVal); 
if (std::numeric_limits<int>::max() == iValue) 
{ 
    dValue = convert<double>(strVal); 
} 

Это немного современный способ сделать это :-)

0

Вы можете сохранить введенные в строку, а затем создать такую ​​функцию, как это:

 
bool GetInt(const char *string, int *out) 
{ 
    char *end; 

    if (!string) 
     return false; 

    int ret_int = strtoul(string, &end, 10); 

    if (*end) 
     return false; 

    *out = ret_int; 
    return true; 
} 

GetInt ("1234", & somevariable) возвращает истину и устанавливает somevariable в 1234. GetInt ("ABC", & somevariable) и GetInt ("1234aaaa", & somevariable) возвращают ложь.Это версия для поплавка, кстати:

 
HOT RESULT_MUST_BE_CHKED NONNULL bool GetFloat(const char *string, float *out) 
{ 
    char *end; 

    if (!string) 
     return false; 

    float ret_float = (float)strtod(string, &end); 

    if (*end) 
     return false; 

    *out = ret_float; 
    return true; 
} 
7

Я хотел бы использовать подход cin.fail() или увеличить «лексического слепок» с использованием Проппер исключений поймать ошибки http://www.boost.org/doc/libs/1_38_0/libs/conversion/lexical_cast.htm

+0

Метод сбоя также может использоваться в строках путем создания строкового потока. I.e: строковый ввод; float f; istringstream s (вход); если(!(s >> f)) {ваш код ошибки} ' – Eponymous

17

Во-первых, ответьте на ваш вопрос. Это на самом деле очень легко, и вы не должны многое изменить в своем коде:

cout << "Please enter x-axis coordinate location : " << flush; 
if (!(cin >> num1)) { 
    cout << "You did not enter a correct number!" << endl; 
    // Leave the program, or do something appropriate: 
    return 1; 
} 

Этот код в основном проверяет, была ли ввод правомерно разобран в виде числа с плавающей точкой - если этого не произошло, он сигнализирует ошибка.

Во-вторых, тип возвращаемого mainсусловсегда быть int, никогда не void.

+0

Что делает' flush'? – 0x499602D2

+1

http://en.cppreference.com/w/cpp/io/manip/flush –

0
//Just do a type cast check 
if ((int)(num1) == num1){ 
//Statements 
} 
+0

Я бы предпочел применить стиль C++ (то есть static_cast) к стилю C здесь. – Flexo

0

Я хотел проверить вход и потребовать, чтобы введенное значение было числовым, чтобы оно могло быть сохранено на числовой переменной. Наконец эта работа для меня (источник: http://www.cplusplus.com/forum/beginner/2957/

int number; 
do{ 
     cout<<"enter a number"<<endl; 
     cin>>number; 
     if ((cin.fail())) { 
     cout<<"error: that's not a number!! try again"<<endl; 
     cin.clear(); // clear the stream 
     //clear the buffer to avoid loop (this part was what I was missing) 
     cin.ignore(std::numeric_limits<int>::max(),'\n'); 
     cout<<"enter a number"<<endl; //ask again 
     cin>>number; 
     } 

} while (cin.fail()); 
Смежные вопросы