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

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

Восстановить пароль Регистрация
 
 
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 00:51     Универсальная функция получения числа через cin #1
Пытался написать универсальную функцию для гарантированного получения числа нужного типа, примерно так:

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, при нем двойка считывается как корректное значение, но поток не очищается от мусора, как я понимаю(а было бы не плохо все это непотребство отбраковывать и требовать повторный ввод).
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,398
30.10.2013, 00:53     Универсальная функция получения числа через cin #2
Запрет на ввод с клавиатуры
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 01:12  [ТС]     Универсальная функция получения числа через cin #3
MrGluck, у вас вроде хорошая репутация, а кидаете мне пример, который уходит в вечный цикл при банальном вводе текста, а также за милую душу пропускает варианты типа 0,,2.
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
30.10.2013, 01:27     Универсальная функция получения числа через cin #4
Цитата Сообщение от Whiteha Посмотреть сообщение
T num(0);
тогда уж
C++
1
T num = T();
в с++11
C++
1
T num{};
Цитата Сообщение от Whiteha Посмотреть сообщение
static_cast<T>(num)
num и так имеет тип T, зачем его кастовать?
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 01:37  [ТС]     Универсальная функция получения числа через cin #5
Jupiter, каст - рудимент от старой версии функции, еще до становлением шаблоном, естественно потом уберу, сразу не сообразил.
С инициализацией вы правы, учту.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.10.2013, 02:18     Универсальная функция получения числа через cin #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;
}
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 02:40  [ТС]     Универсальная функция получения числа через cin #7
alsav22, вроде ближе к истине, но при вводе текста уходит в бесконечный цикл=\
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,398
30.10.2013, 02:42     Универсальная функция получения числа через cin #8
Цитата Сообщение от Whiteha Посмотреть сообщение
у вас вроде хорошая репутация
репутация - ничто, она знания не показывает. Человек с 0 репой и 2 сообщениями может дать более дельный совет.
Цитата Сообщение от Whiteha Посмотреть сообщение
кидаете мне пример, который уходит в вечный цикл при банальном вводе текста
видимо вы что-то делаете не так ибо:
Универсальная функция получения числа через cin Универсальная функция получения числа через cin
Во втором варианте 0,,2 не пропускает. А в первом - ну что ж, std::cin так реализован. Задача моих исходников - уберечь от краха, его здесь нет. Infinity loop возникает лишь если в программу для считывания числа как дурак подавать один текст.
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,398
30.10.2013, 02:44     Универсальная функция получения числа через cin #9
Да и бесконечным циклом назвать это даже нельзя т.к. из него можно выйти при корректных данных.
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 02:47  [ТС]     Универсальная функция получения числа через cin #10
MrGluck, попробуйте вводить не посимвольно, а строкой. С одной стороны я блогадарен за то, что вы проявили внимание к теме, а с другой это не то что нужно и не работает.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.10.2013, 02:48     Универсальная функция получения числа через cin #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;
}
Миниатюры
Универсальная функция получения числа через cin  
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,398
30.10.2013, 02:50     Универсальная функция получения числа через cin #12
УМВР, ЧЯДНТ?
Универсальная функция получения числа через cin
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,398
30.10.2013, 02:52     Универсальная функция получения числа через cin #13
УМВР2
Универсальная функция получения числа через cin
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,398
30.10.2013, 02:54     Универсальная функция получения числа через cin #14
Цитата Сообщение от alsav22 Посмотреть сообщение
Где что уходит?
Да он наверняка сам накосячил где то

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

Не по теме:

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

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

Добавлено через 1 минуту
У вас Linux?
MrGluck
Ворчун
Эксперт С++
 Аватар для MrGluck
4919 / 2662 / 243
Регистрация: 29.11.2010
Сообщений: 7,398
30.10.2013, 03:02     Универсальная функция получения числа через cin #18
Цитата Сообщение от alsav22 Посмотреть сообщение
У вас Linux?
У меня в CB с мингв тоже вечный цикл. После добавления хедеров cstdlib, limits и ввода abcd - infinity loop как на скрине выше.
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 03:03  [ТС]     Универсальная функция получения числа через cin #19
alsav22,
код getNum копия вашего
Миниатюры
Универсальная функция получения числа через cin   Универсальная функция получения числа через cin  
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.10.2013, 03:05     Универсальная функция получения числа через cin
Еще ссылки по теме:

Функция cin.getline() C++
C++ Объясните пожалуйста как работают cin.good(), cin.sync(), cin.clear()
C++ Универсальная функция считывания переменных из бинарного файла

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

Или воспользуйтесь поиском по форуму:
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 03:05  [ТС]     Универсальная функция получения числа через cin #20
alsav22, да, Debian Wheezy i386

Добавлено через 1 минуту
MrGluck, вы уж простите что вам не отвечаю со скринами, думаю проблема зацикливания имеет одну общую причину.
Yandex
Объявления
30.10.2013, 03:05     Универсальная функция получения числа через cin
Ответ Создать тему
Опции темы

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