Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
Whiteha
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
#1

Универсальная функция получения числа через cin

30.10.2013, 00:51. Просмотров 1127. Ответов 31
Метки нет (Все метки)

Пытался написать универсальную функцию для гарантированного получения числа нужного типа, примерно так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Функция для безопасного получения числа указанного типа,
// оставляет поток cin в корректном состояние, вроде бы гарантированно
template <class T = double>
T getNum(const T &min = numeric_limits<T>::lowest(),
         const T &max = numeric_limits<T>::max())
{
    if (max < min)
        throw string("Ошибка в аргументах getNum, минимум больше максимума");
 
    // Для очистки потока от некорректного состояния
    auto clear = []()
    {
        cin.clear();
        cin.ignore(numeric_limits<std::streamsize>::max(), '\n');
        //cin.sync();
        //cin.clear();
    };
 
    T num(0);
 
    do
    {
        cout << "Число должно быть больше или равно " << min
             << " и меньше или равно "                << max
             << endl;
 
        cin >> num;
 
        if (cin.fail() || cin.bad() || cin.eof())
        {
            clear();
            continue;
        }
 
    }
    while((static_cast<T>(num) < min) || (static_cast<T>(num) > max));
 
    clear();
 
    return static_cast<T>(num);
}
но что-то она не очень работает, точнее не обрабатывает как должна ввод текста вместо числа.
В частности при вызове с аргументом шаблона T = long double и рандовном набивание символов
num присваивается 0, а clear то ли не отрабатывает как надо, то ли еще что... в общем все работает не так.
Светлые умы, помогите довести до ума кто знает как

Добавлено через 18 минут
Кстати также некорректно обрабатывает ввод типа 2,,3, при нем двойка считывается как корректное значение, но поток не очищается от мусора, как я понимаю(а было бы не плохо все это непотребство отбраковывать и требовать повторный ввод).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.10.2013, 00:51
Ответы с готовыми решениями:

Заполнить массив цифрами числа, считанного через cin
Здрасти, как ввести в массив int mMass число 12345 с помощью cin&gt;&gt;? Нужно...

Как работает cin.peek, cin,get, cin.ignore, cin.clear?
Здравствуйте, товарищи и не товарищи!:) Я только начал изучать C++, а уже...

Универсальная функция
Напишите пожалуйста прогу.Написать универсальную функцию для вычислениия...

Какую библиотеку надо подключать чтоб работала функция _getch() и функция cin.get()?
какую библиотеку надо подключать чтоб работала функция _getch() и функция...

Универсальная функция считывания переменных из бинарного файла
Подскажите, написал запись в бинарный файл переменных, не могу считать, точнее...

31
MrGluck
Модератор
Эксперт CЭксперт С++
8078 / 4930 / 1431
Регистрация: 29.11.2010
Сообщений: 13,357
30.10.2013, 00:53 #2
Запрет на ввод с клавиатуры
0
Whiteha
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 01:12  [ТС] #3
MrGluck, у вас вроде хорошая репутация, а кидаете мне пример, который уходит в вечный цикл при банальном вводе текста, а также за милую душу пропускает варианты типа 0,,2.
0
Jupiter
Каратель
Эксперт С++
6569 / 3990 / 400
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
30.10.2013, 01:27 #4
Цитата Сообщение от Whiteha Посмотреть сообщение
T num(0);
тогда уж
C++
1
T num = T();
в с++11
C++
1
T num{};
Цитата Сообщение от Whiteha Посмотреть сообщение
static_cast<T>(num)
num и так имеет тип T, зачем его кастовать?
0
Whiteha
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 01:37  [ТС] #5
Jupiter, каст - рудимент от старой версии функции, еще до становлением шаблоном, естественно потом уберу, сразу не сообразил.
С инициализацией вы правы, учту.
0
alsav22
5441 / 4836 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.10.2013, 02:18 #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Функция для безопасного получения числа указанного типа,
// оставляет поток cin в корректном состояние, вроде бы гарантированно
template <class T>
T getNum(const T &min = numeric_limits<T>::lowest(),
         const T &max = numeric_limits<T>::max())
{
    if (max < min)
        throw string("Ошибка в аргументах getNum, минимум больше максимума");
 
    T num(0);
    
    cin.clear();
    cin.ignore(cin.rdbuf()->in_avail());
    do
    {
        cout << "Число должно быть больше или равно " << min
                 << " и меньше или равно "            << max
                 << endl;
 
        while (!(cin >> num) || (cin.peek() != '\n'))
        {
            cin.clear();
            cin.ignore(cin.rdbuf()->in_avail());
            cout << "Ошибка ввода!" << endl;
        }
    
    } while (num < min || num > max);
    
    return num;
}
0
Whiteha
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 02:40  [ТС] #7
alsav22, вроде ближе к истине, но при вводе текста уходит в бесконечный цикл=\
0
MrGluck
Модератор
Эксперт CЭксперт С++
8078 / 4930 / 1431
Регистрация: 29.11.2010
Сообщений: 13,357
30.10.2013, 02:42 #8
Цитата Сообщение от Whiteha Посмотреть сообщение
у вас вроде хорошая репутация
репутация - ничто, она знания не показывает. Человек с 0 репой и 2 сообщениями может дать более дельный совет.
Цитата Сообщение от Whiteha Посмотреть сообщение
кидаете мне пример, который уходит в вечный цикл при банальном вводе текста
видимо вы что-то делаете не так ибо:
Универсальная функция получения числа через cin
Универсальная функция получения числа через cin

Во втором варианте 0,,2 не пропускает. А в первом - ну что ж, std::cin так реализован. Задача моих исходников - уберечь от краха, его здесь нет. Infinity loop возникает лишь если в программу для считывания числа как дурак подавать один текст.
0
MrGluck
Модератор
Эксперт CЭксперт С++
8078 / 4930 / 1431
Регистрация: 29.11.2010
Сообщений: 13,357
30.10.2013, 02:44 #9
Да и бесконечным циклом назвать это даже нельзя т.к. из него можно выйти при корректных данных.
0
Whiteha
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 02:47  [ТС] #10
MrGluck, попробуйте вводить не посимвольно, а строкой. С одной стороны я блогадарен за то, что вы проявили внимание к теме, а с другой это не то что нужно и не работает.
0
alsav22
5441 / 4836 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.10.2013, 02:48 #11
Цитата Сообщение от Whiteha Посмотреть сообщение
alsav22, вроде ближе к истине, но при вводе текста уходит в бесконечный цикл=\
Где что уходит?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <iostream>
using namespace std;
 
// Функция для безопасного получения числа указанного типа,
// оставляет поток cin в корректном состояние, вроде бы гарантированно
template <class T>
T getNum(const T &min = numeric_limits<T>::lowest(),
         const T &max = numeric_limits<T>::max())
{
    if (max < min)
        throw string("Ошибка в аргументах getNum, минимум больше максимума");
 
    T num(0);
    
    cin.clear();
    cin.ignore(cin.rdbuf()->in_avail());
    do
    {
        cout << "Число должно быть больше или равно " << min
                 << " и меньше или равно "            << max
                 << endl;
 
        while (!(cin >> num) || (cin.peek() != '\n'))
        {
            cin.clear();
            cin.ignore(cin.rdbuf()->in_avail());
            cout << "Ошибка ввода!" << endl;
        }
    
    } while (num < min || num > max);
    
    return num;
}
 
int main()
{
    setlocale(0, "");
    
    getNum(2, 6);
    
    system("pause");
    return 0;
}
0
Миниатюры
Универсальная функция получения числа через cin  
MrGluck
Модератор
Эксперт CЭксперт С++
8078 / 4930 / 1431
Регистрация: 29.11.2010
Сообщений: 13,357
30.10.2013, 02:50 #12
УМВР, ЧЯДНТ?
Универсальная функция получения числа через cin
0
MrGluck
Модератор
Эксперт CЭксперт С++
8078 / 4930 / 1431
Регистрация: 29.11.2010
Сообщений: 13,357
30.10.2013, 02:52 #13
УМВР2
Универсальная функция получения числа через cin
0
MrGluck
Модератор
Эксперт CЭксперт С++
8078 / 4930 / 1431
Регистрация: 29.11.2010
Сообщений: 13,357
30.10.2013, 02:54 #14
Цитата Сообщение от alsav22 Посмотреть сообщение
Где что уходит?
Да он наверняка сам накосячил где то

Добавлено через 19 секунд

Не по теме:

Почему в 3 сообщения то?

0
alsav22
5441 / 4836 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.10.2013, 02:55 #15
Цитата Сообщение от MrGluck Посмотреть сообщение
Да он наверняка сам накосячил где то
Может ТС под бесконечным циклом что-то другое имеет ввиду? Может ему нужен сразу выход из цикла ввода, если некоректный ввод. Но это не проблема и самому сделать.
0
Whiteha
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 02:55  [ТС] #16
alsav22,
Ввод "abcd", аргумент шаблона long double, компилятор из gcc 4.7:
0
Миниатюры
Универсальная функция получения числа через cin  
alsav22
5441 / 4836 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
30.10.2013, 02:59 #17
Вы покажите, что вводите, и код, который используете. Я же на скрине показываю, что ввожу, и код показываю, который использую.

Добавлено через 1 минуту
У вас Linux?
0
MrGluck
Модератор
Эксперт CЭксперт С++
8078 / 4930 / 1431
Регистрация: 29.11.2010
Сообщений: 13,357
30.10.2013, 03:02 #18
Цитата Сообщение от alsav22 Посмотреть сообщение
У вас Linux?
У меня в CB с мингв тоже вечный цикл. После добавления хедеров cstdlib, limits и ввода abcd - infinity loop как на скрине выше.
0
Whiteha
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 03:03  [ТС] #19
alsav22,
код getNum копия вашего
0
Миниатюры
Универсальная функция получения числа через cin   Универсальная функция получения числа через cin  
Whiteha
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 03:05  [ТС] #20
alsav22, да, Debian Wheezy i386

Добавлено через 1 минуту
MrGluck, вы уж простите что вам не отвечаю со скринами, думаю проблема зацикливания имеет одну общую причину.
0
30.10.2013, 03:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.10.2013, 03:05

Отбрасывание "мусорных" данных при вводе числа через cin
Имеется задача, когда необходимо ввести с клавиатуры число и обработать его. ...

Универсальная функция для приема разных двумерных массивов
В программе у меня много двумерных массивом разной размерности. Мне нужна одна...

Защита от дурака при вводе текста с помощью: cin.get cin.clear cin.sync
Доброго времени суток. На С++ учусь с недавних пор. Имеется стандартная &quot;защита...


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

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

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