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

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

Войти
Регистрация
Восстановить пароль
 
 
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
#1

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

30.10.2013, 00:51. Просмотров 1011. Ответов 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 (C++):

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

Универсальная функция - C++
Напишите пожалуйста прогу.Написать универсальную функцию для вычислениия заданных выражений.В main() обеспечить вызов этой функции и...

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

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

Универсальная функция для приема разных двумерных массивов - C++
В программе у меня много двумерных массивом разной размерности. Мне нужна одна функция (общая) чтобы работала на все массивы. Функция...

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

31
MrGluck
Модератор
Эксперт CЭксперт С++
7498 / 4614 / 694
Регистрация: 29.11.2010
Сообщений: 12,633
30.10.2013, 00:53 #2
Запрет на ввод с клавиатуры
0
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 01:12  [ТС] #3
MrGluck, у вас вроде хорошая репутация, а кидаете мне пример, который уходит в вечный цикл при банальном вводе текста, а также за милую душу пропускает варианты типа 0,,2.
0
Jupiter
Каратель
Эксперт С++
6561 / 3982 / 227
Регистрация: 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 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 01:37  [ТС] #5
Jupiter, каст - рудимент от старой версии функции, еще до становлением шаблоном, естественно потом уберу, сразу не сообразил.
С инициализацией вы правы, учту.
0
alsav22
5428 / 4823 / 442
Регистрация: 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 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 02:40  [ТС] #7
alsav22, вроде ближе к истине, но при вводе текста уходит в бесконечный цикл=\
0
MrGluck
Модератор
Эксперт CЭксперт С++
7498 / 4614 / 694
Регистрация: 29.11.2010
Сообщений: 12,633
30.10.2013, 02:42 #8
Цитата Сообщение от Whiteha Посмотреть сообщение
у вас вроде хорошая репутация
репутация - ничто, она знания не показывает. Человек с 0 репой и 2 сообщениями может дать более дельный совет.
Цитата Сообщение от Whiteha Посмотреть сообщение
кидаете мне пример, который уходит в вечный цикл при банальном вводе текста
видимо вы что-то делаете не так ибо:
Универсальная функция получения числа через cin Универсальная функция получения числа через cin
Во втором варианте 0,,2 не пропускает. А в первом - ну что ж, std::cin так реализован. Задача моих исходников - уберечь от краха, его здесь нет. Infinity loop возникает лишь если в программу для считывания числа как дурак подавать один текст.
0
MrGluck
Модератор
Эксперт CЭксперт С++
7498 / 4614 / 694
Регистрация: 29.11.2010
Сообщений: 12,633
30.10.2013, 02:44 #9
Да и бесконечным циклом назвать это даже нельзя т.к. из него можно выйти при корректных данных.
0
Whiteha
Программист
33 / 33 / 4
Регистрация: 08.07.2011
Сообщений: 190
Записей в блоге: 1
30.10.2013, 02:47  [ТС] #10
MrGluck, попробуйте вводить не посимвольно, а строкой. С одной стороны я блогадарен за то, что вы проявили внимание к теме, а с другой это не то что нужно и не работает.
0
alsav22
5428 / 4823 / 442
Регистрация: 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Эксперт С++
7498 / 4614 / 694
Регистрация: 29.11.2010
Сообщений: 12,633
30.10.2013, 02:50 #12
УМВР, ЧЯДНТ?
Универсальная функция получения числа через cin
0
MrGluck
Модератор
Эксперт CЭксперт С++
7498 / 4614 / 694
Регистрация: 29.11.2010
Сообщений: 12,633
30.10.2013, 02:52 #13
УМВР2
Универсальная функция получения числа через cin
0
MrGluck
Модератор
Эксперт CЭксперт С++
7498 / 4614 / 694
Регистрация: 29.11.2010
Сообщений: 12,633
30.10.2013, 02:54 #14
Цитата Сообщение от alsav22 Посмотреть сообщение
Где что уходит?
Да он наверняка сам накосячил где то

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

Не по теме:

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

0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
30.10.2013, 02:55 #15
Цитата Сообщение от MrGluck Посмотреть сообщение
Да он наверняка сам накосячил где то
Может ТС под бесконечным циклом что-то другое имеет ввиду? Может ему нужен сразу выход из цикла ввода, если некоректный ввод. Но это не проблема и самому сделать.
0
30.10.2013, 02:55
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.10.2013, 02:55
Привет! Вот еще темы с ответами:

Объясните пожалуйста как работают cin.good(), cin.sync(), cin.clear() - C++
Такая проблема: сдаю в вуза лабораторные по программированию, писал все сам, до этого c++ не изучал, поэтому возникали некоторые проблемы....

Функция getline(cin,.) - C++
Здравствуйте уважаемые программисты. По темам пробежался getline(), но чет не понял, проблема, почему при вводе данных о первом человеке...

Функция чтения cin.get - C++
Подскажите пожалуйста почему функция cin.get(str, len, '0') считывает не (len - 1) как должна, а (len - 2) символов ? #include &lt;iostream&gt;...

Функция cin.getline() - C++
Имеется часть кода: void EditName(Account &amp;acc) { delete acc.name; char nam; cout&lt;&lt;&quot;Введите новое имя: &quot;; ...


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

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

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