Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
1

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

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

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

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
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.10.2013, 00:51
Ответы с готовыми решениями:

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

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

Универсальная функция
1.Определим функцию K(n), которая определяет количество цифр в заданном натуральном числе n. 2....

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

31
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
30.10.2013, 00:53 2
Запрет на ввод с клавиатуры
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 01:12  [ТС] 3
MrGluck, у вас вроде хорошая репутация, а кидаете мне пример, который уходит в вечный цикл при банальном вводе текста, а также за милую душу пропускает варианты типа 0,,2.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
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
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 01:37  [ТС] 5
Jupiter, каст - рудимент от старой версии функции, еще до становлением шаблоном, естественно потом уберу, сразу не сообразил.
С инициализацией вы правы, учту.
0
5498 / 4893 / 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
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 02:40  [ТС] 7
alsav22, вроде ближе к истине, но при вводе текста уходит в бесконечный цикл=\
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
30.10.2013, 02:42 8
Цитата Сообщение от Whiteha Посмотреть сообщение
у вас вроде хорошая репутация
репутация - ничто, она знания не показывает. Человек с 0 репой и 2 сообщениями может дать более дельный совет.
Цитата Сообщение от Whiteha Посмотреть сообщение
кидаете мне пример, который уходит в вечный цикл при банальном вводе текста
видимо вы что-то делаете не так ибо:
Универсальная функция получения числа через cin
Универсальная функция получения числа через cin

Во втором варианте 0,,2 не пропускает. А в первом - ну что ж, std::cin так реализован. Задача моих исходников - уберечь от краха, его здесь нет. Infinity loop возникает лишь если в программу для считывания числа как дурак подавать один текст.
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
30.10.2013, 02:44 9
Да и бесконечным циклом назвать это даже нельзя т.к. из него можно выйти при корректных данных.
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 02:47  [ТС] 10
MrGluck, попробуйте вводить не посимвольно, а строкой. С одной стороны я блогадарен за то, что вы проявили внимание к теме, а с другой это не то что нужно и не работает.
0
5498 / 4893 / 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;
}
Миниатюры
Универсальная функция получения числа через cin  
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
30.10.2013, 02:50 12
УМВР, ЧЯДНТ?
Универсальная функция получения числа через cin
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
30.10.2013, 02:52 13
УМВР2
Универсальная функция получения числа через cin
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
30.10.2013, 02:54 14
Цитата Сообщение от alsav22 Посмотреть сообщение
Где что уходит?
Да он наверняка сам накосячил где то

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

Не по теме:

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

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

Добавлено через 1 минуту
У вас Linux?
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
30.10.2013, 03:02 18
Цитата Сообщение от alsav22 Посмотреть сообщение
У вас Linux?
У меня в CB с мингв тоже вечный цикл. После добавления хедеров cstdlib, limits и ввода abcd - infinity loop как на скрине выше.
0
Программист
33 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 03:03  [ТС] 19
alsav22,
код getNum копия вашего
Миниатюры
Универсальная функция получения числа через cin   Универсальная функция получения числа через cin  
0
Программист
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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.10.2013, 03:05
Помогаю со студенческими работами здесь

Универсальная функция
Здравствуйте! Прошу помощи. Можно сделать какую-нибудь универсальную функцию, которой можно было бы...

Универсальная функция Ajax
Хочу сделать универсальную функцию Ajax, но не получаеться получить ответ сразу, функция...

Универсальная функция вывода
Господа, пытаюсь сделать функцию, которая напечатает массив, и будет универсальна для всех типов и...

Универсальная функция запросов в базу
Здравствуйте. Есть несколько мест в коде где идет 6-8 запросов в базу, запросы различные...


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

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