3 / 3 / 2
Регистрация: 18.12.2014
Сообщений: 64
1

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

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

Author24 — интернет-сервис помощи студентам
Фрагмент кода:
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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.01.2015, 13:21
Ответы с готовыми решениями:

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

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

Функция некорректно работает
Функция компилируется, но постоянно один и тот же ответ. y=0000... Где допущена ошибка? ...

Функция работает некорректно
Здравствуйте! Задача, написать функцию myfuc по заданному вызову ее int main(int argc, char...

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

Добавлено через 5 минут
Но это слишком: проще поставить числовое ограничение в пределах типа, т.к. ну очень большие числа тут вряд ли будут использоваться.
0
3 / 3 / 2
Регистрация: 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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.02.2015, 18:11
Помогаю со студенческими работами здесь

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

Функция работает некорректно
Добрый день! Сделал функцию, которая должна удалить определённый символ в определённом тексте....

Некорректно работает функция eoln
Есть текстовый файл. Вот его содержание: 2 4 7 3 9 1 5 7 4 5 6 4 2 1 7 8 9 4 3 2 assignFile(f,...

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru