Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

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

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

09.01.2015, 13:21. Просмотров 435. Ответов 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)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.01.2015, 13:21
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Некорректно работает функция проверки на численность (C++):

Функция работает некорректно - C++
#include &lt;iostream&gt; using namespace std; short fill(double*, short); const short size = 5; int main() { double array;...

Некорректно работает функция - C++
Функция Small_S должна находить короткое слово в строке str, а она почему-то выводит первое слово! Помогите решить проблему, буду очень...

Функция работает некорректно - C++
написал функцию,возвращающий нажатую клавишу: char func2(){ if(_kbhit()){ char c; c=_getch(); return c; } return 0; ...

Некорректно работает функция Delete - C++
Слепил прожку. Которая должна записать в файл информацию о стране. А потом функция Делит должна по названию страны удалить всю информацию о...

Некорректно работает функция добавления, указать ошибку - C++
Здравствуйте, в моей программе некорректно работает добавление элемента, функция addBook. Также прошу проверить правильность работы...

Некорректно работает функция рандомайз при заполнении массива - C++
Задача - внести случайные числа в динамический массив. Проблема - почему-то при первом запуске программы в первый элемент массива...

11
casper007
68 / 68 / 23
Регистрация: 12.12.2013
Сообщений: 420
09.01.2015, 14:01 #2
Ну так "дофига" это есть переполнение типа. Логично, что оно меньше нуля
0
Tulosba
:)
Эксперт С++
4705 / 3240 / 297
Регистрация: 19.02.2013
Сообщений: 9,046
09.01.2015, 14:24 #3
Во-первых, от while в 3 строке проку ноль, т.к. в нем находится return. Т.е. это вырождается в обычный if.
Во-вторых, чтобы проверять значение на допустимый диапазон нужно сначала это значение считать в переменную более широкого диапазона. Переменная типа int всегда будет находиться в диапазоне [INT_MIN..INT_MAX]. И тут, кстати, неравенства должны быть строгие.
0
Иван_Богданов
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 должна влезать в тип. Она не хочет выполнять мои условия! В логе отладчика никаких ошибок нет. В чем еще может быть проблема?
0
Миниатюры
Некорректно работает функция проверки на численность  
Tulosba
:)
Эксперт С++
4705 / 3240 / 297
Регистрация: 19.02.2013
Сообщений: 9,046
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
0
Иван_Богданов
3 / 3 / 0
Регистрация: 18.12.2014
Сообщений: 64
09.01.2015, 16:34  [ТС] #6
Это хорошо, но в программе условия: i должна быть числом, влезать в тип и быть строго больше нуля. Потому что если не выполняется хотя бы одно, прога дальше сходит с ума. Как же быть?
0
Enno
267 / 170 / 38
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
09.01.2015, 16:49 #7
Возьми long long, вместо int.
0
Иван_Богданов
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;
}
0
Иван_Богданов
3 / 3 / 0
Регистрация: 18.12.2014
Сообщений: 64
09.01.2015, 17:51  [ТС] #9
Могу даже картиночку запилить:
Вот мы вводим 2,5ккк - это больше int, но меньше long long
Далее вводим "дофига" - та ф-я дает фэиловый бит
С точечкой все правильно
С -5 тоже
На 10 выходим из цикла
0
Миниатюры
Некорректно работает функция проверки на численность  
Enno
267 / 170 / 38
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
09.01.2015, 18:19 #10
Вот ты и выяснил когда ещё fail наступает. Поздравляю, начинай парсить строку посимвольно.
0
Иван_Богданов
3 / 3 / 0
Регистрация: 18.12.2014
Сообщений: 64
09.01.2015, 18:31  [ТС] #11
Спасибо.

Добавлено через 5 минут
Но это слишком: проще поставить числовое ограничение в пределах типа, т.к. ну очень большие числа тут вряд ли будут использоваться.
0
Иван_Богданов
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();}
Мне тоже это кажется странным, но это работает без проблем. Просто эта ф-я должна заново начинать выполнение программы, но операторы безусловного перехода нельзя юзать в разных ф-ях. Есть ли еще способы заставить прогу перейти из одной ф-и в другую?
0
19.02.2015, 18:11
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.02.2015, 18:11
Привет! Вот еще темы с ответами:

Некорректно работает функция sum! Она должна искать сумму между первым и последним положительным элементами! - C++
Некорректно работает функция sum! Она должна искать сумму между первым и последним положительным элементами! Когда первый элемент...

Исправить задачу (написать прогу, которая запрашивает численность населения Земли и численность населения США) - C++
Задача: написать прогу, которая запрашивает численность населения Земли и численность населения США. Сохранить информацию в переменных типа...

Функция проверки пароля - C++
Подскажите по поводу проверки пароля, при вводе пароль, не пароль все равно пишет привет, почему strcmp не сравнивает int...

Функция проверки введенного символа - C++
Здравствуйте помогите написать функцию которая будет проверять правильный символ т.е чтобы если пользователь написал буквы или...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru