Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Иван_Богданов
3 / 3 / 0
Регистрация: 18.12.2014
Сообщений: 64
#1

Некорректно работает функция проверки на численность - C++

09.01.2015, 13:21. Просмотров 360. Ответов 11
Метки нет (Все метки)

Фрагмент кода:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//...
bool is_number() { //*
    while(cin.fail()) {
        cin.clear();
        cin.sync();
        return false;} 
    return true;
}
 
int main() {
int i;
//...
do { cout << "Количество значений = "; cin >> i;
if(!is_number()) //проверяем переменную, число ли она...
    cout << "Exception: Invalid non-numeric value!\n\n"; 
if(i<=INT_MIN || i>=INT_MAX) //и умещается ли в тип
    cout << "Exception: Invalid too large or too small value!\n\n";
if(i<=0) //наше условие: строго больше нуля
    cout << "Exception: Invalid less than or equal to zero value!\n\n";
/*если какое-то условие не выполняется, прога выведет сообщение об ошибке*/
} while(!is_number() || i<=INT_MIN || i>=INT_MAX || i<=0); //и крутим цикл, пока хотя бы одно условие неверно
//...
* - "устанавливает бит "fail", если встречает символы, отличные от цифр. Затем, программа очищает бит "fail" и удаляет некорректный символ из потока, затем продолжает выполнение." Эта аллюзия на ф-ю с сайта микромягкого:...
C++
1
2
3
4
5
6
if (cin.fail())
      {
         cin.clear();
         char c;
         cin >> c;
      }
Вроде, все просто, но программа некорректно работает: вводим букву, прога выводит нужную ошибку о наличии букв и выкидывает из цикла, как будто все нормально.
Вводим число "дофига" (большее, чем вмещает тип) - та же ошибка и выброс из цикла.
Но если ведем число меньше или равно нулю, все нормально: нужное сообщение об ошибке и повтор цикла. Если потом ввести число "дофига", то выдаст две ошибки: о нечисловом значении, которое мешьне или равно нулю.
В чем же дело? (Компилятор от микромягкого VS2010)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.01.2015, 13:21     Некорректно работает функция проверки на численность
Посмотрите здесь:

Функция работает некорректно C++
C++ Некорректно работает функция sum! Она должна искать сумму между первым и последним положительным элементами!
C++ Некорректно работает функция
Функция проверки пароля C++
Исправить задачу (написать прогу, которая запрашивает численность населения Земли и численность населения США) C++
C++ Некорректно работает функция рандомайз при заполнении массива
Функция проверки введенного символа C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
casper007
67 / 67 / 22
Регистрация: 12.12.2013
Сообщений: 395
09.01.2015, 14:01     Некорректно работает функция проверки на численность #2
Ну так "дофига" это есть переполнение типа. Логично, что оно меньше нуля
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
09.01.2015, 14:24     Некорректно работает функция проверки на численность #3
Во-первых, от while в 3 строке проку ноль, т.к. в нем находится return. Т.е. это вырождается в обычный if.
Во-вторых, чтобы проверять значение на допустимый диапазон нужно сначала это значение считать в переменную более широкого диапазона. Переменная типа int всегда будет находиться в диапазоне [INT_MIN..INT_MAX]. И тут, кстати, неравенства должны быть строгие.
Иван_Богданов
3 / 3 / 0
Регистрация: 18.12.2014
Сообщений: 64
09.01.2015, 15:29  [ТС]     Некорректно работает функция проверки на численность #4
Конечно, спасибо, но до сих пор прога успешно выходит из цикла при вводе числа "дофига". Ошибка в наличии букв. Может, эта функция изначально неправильно работала...
C++
1
2
3
4
5
6
7
bool is_number() {
    if(cin.fail()) {
        cin.clear();
        cin.sync();
        return false;
    } else return true;
}
Если ее вызов убрать из цикла, то он заканчивается при вводе того же числа, хотя в условии повтора...
C++
1
2
3
4
//...
} while(i<INT_MIN || i>INT_MAX || i<=0);
cout << "Success\n";
system("pause");
явно указано, что i должна влезать в тип. Она не хочет выполнять мои условия! В логе отладчика никаких ошибок нет. В чем еще может быть проблема?
Миниатюры
Некорректно работает функция проверки на численность  
Tulosba
:)
Эксперт С++
4387 / 3230 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
09.01.2015, 15:43     Некорректно работает функция проверки на численность #5
Цитата Сообщение от Иван_Богданов Посмотреть сообщение
что i должна влезать в тип.
i не может НИКАК лежать вне диапазона INT_MIN, INT_MAX.
Когда ты вводишь с клавиатуры нечто, что не помещается в этот диапазон, в переменную просто записывается максимальное значение. Пример:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;
     
int main() {
     
    int i = 0;
    cin >> i;
    cout << i << endl;
    return 0;
}
http://ideone.com/Z9cRjn
Иван_Богданов
3 / 3 / 0
Регистрация: 18.12.2014
Сообщений: 64
09.01.2015, 16:34  [ТС]     Некорректно работает функция проверки на численность #6
Это хорошо, но в программе условия: i должна быть числом, влезать в тип и быть строго больше нуля. Потому что если не выполняется хотя бы одно, прога дальше сходит с ума. Как же быть?
Enno
266 / 169 / 38
Регистрация: 25.08.2014
Сообщений: 1,088
Записей в блоге: 1
09.01.2015, 16:49     Некорректно работает функция проверки на численность #7
Возьми long long, вместо int.
Иван_Богданов
3 / 3 / 0
Регистрация: 18.12.2014
Сообщений: 64
09.01.2015, 17:40  [ТС]     Некорректно работает функция проверки на численность #8
Спасибо, надо попробовать.

Добавлено через 20 минут
Хмм, если подправить тело цикла, сделав проверку if лестницей if-else, то выводит правильные сообщения об ошибках. Но если ввести "нечто", превышающее long long, выведет сообщение о наличии букв!
C++
1
2
3
4
5
do { cout << "Количество значений = "; cin >> i;
if(!is_number()) cout << "Exception: Invalid non-numeric value!\n";
else if(i<INT_MIN || i>INT_MAX) cout << "Exception: Invalid too large or too small value!\n";
else if(i<=0) cout << "Exception: Invalid less than or equal to zero value!\n";
} while(!is_number() || i<INT_MIN || i>INT_MAX || i<=0);
Нужна проверка на влезаемость в long long? Или так и должно быть, значит эта ф-я проверяет не только наличие букв в потоке?
C++
1
2
3
4
5
6
7
bool is_number() {
    if(cin.fail()) {
        cin.clear();
        cin.sync();
        return false;
    } else return true;
}
Иван_Богданов
3 / 3 / 0
Регистрация: 18.12.2014
Сообщений: 64
09.01.2015, 17:51  [ТС]     Некорректно работает функция проверки на численность #9
Могу даже картиночку запилить:
Вот мы вводим 2,5ккк - это больше int, но меньше long long
Далее вводим "дофига" - та ф-я дает фэиловый бит
С точечкой все правильно
С -5 тоже
На 10 выходим из цикла
Миниатюры
Некорректно работает функция проверки на численность  
Enno
266 / 169 / 38
Регистрация: 25.08.2014
Сообщений: 1,088
Записей в блоге: 1
09.01.2015, 18:19     Некорректно работает функция проверки на численность #10
Вот ты и выяснил когда ещё fail наступает. Поздравляю, начинай парсить строку посимвольно.
Иван_Богданов
3 / 3 / 0
Регистрация: 18.12.2014
Сообщений: 64
09.01.2015, 18:31  [ТС]     Некорректно работает функция проверки на численность #11
Спасибо.

Добавлено через 5 минут
Но это слишком: проще поставить числовое ограничение в пределах типа, т.к. ну очень большие числа тут вряд ли будут использоваться.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.02.2015, 18:11     Некорректно работает функция проверки на численность
Еще ссылки по теме:

Некорректно работает функция добавления, указать ошибку C++
Функция проверки признаков делимости C++
C++ Функция работает некорректно
C++ Функция проверки двумерного массива C++
C++ Функция проверки делимости числа на 8

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Иван_Богданов
3 / 3 / 0
Регистрация: 18.12.2014
Сообщений: 64
19.02.2015, 18:11  [ТС]     Некорректно работает функция проверки на численность #12
Просто парсить строку здесь непрагматично: можно поставить своего рода костыль: запилить булевскую функцию, которая проверяет значения переменной и которая что-то делает, если значения не совпадают. (Почему-то прога странно шарится в потоке (или я неправильно заставляю ее шариться): условие не совпало, но все равно продолжает.) Например:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
bool check(long long i, long long min, long long max) {
//моя ф-я принимает три аргумента: i, min, max
    if(!is_number())        {return false;}
    if(i>INT_MAX)           {return false;}
    if(i<=0)                {return false;}
    if(i>1000000)           {return false;}
    if(abs(min)>INT_MAX)    {return false;}
    if(abs(min)>INT_MAX)    {return false;}
    if(max<=min)            {return false;}
//если подходят мои условия if-ов, возвращаем ложь
return true;
//если все в порядке - правду
}
(...В таком виде все нормально работает.) Далее:
C++
1
2
3
4
5
6
7
8
int main()
{ /*...бла-бла-бла...*/
cout << "Количество значений = "; cin >> i;
cout << "Мин. значение = "; cin >> min;
cout << "Макс. значение = "; cin >> max;
//эти i, min, max - другие переменные
if(!check(i,min,max)) {fatal_error();}
//если наша ф-я выдала ложь, запускаем ф-ю fatal_error()
...которая, в свою очередь...
C++
1
2
3
4
void fatal_error() {
    cout << "\n\nYou have broken the program.\n";
//выводит сообщение об ошибке, и при нажатии любой клавиши запускает основную ф-ю main()
    if(_getch()) main();}
Мне тоже это кажется странным, но это работает без проблем. Просто эта ф-я должна заново начинать выполнение программы, но операторы безусловного перехода нельзя юзать в разных ф-ях. Есть ли еще способы заставить прогу перейти из одной ф-и в другую?
Yandex
Объявления
19.02.2015, 18:11     Некорректно работает функция проверки на численность
Ответ Создать тему
Опции темы

Текущее время: 07:55. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru