Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/585: Рейтинг темы: голосов - 585, средняя оценка - 4.56
 Аватар для Петр1
3 / 1 / 0
Регистрация: 09.10.2012
Сообщений: 25

Проверка на правильность ввода с клавиатуры

23.10.2012, 12:12. Показов 123244. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
задача: пользователь вводит с клавиатуры цифру, нужно проверить что пользователь действительно ввел цифру, а не букву, знак или сочетание вышесказанного (db, 24d, 2k5)

вот на чем я остановился

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
int n;
bool exit;
 
cin>>n;
exit=true;
while(exit){
    if((n>'a' || n<'Z')) {
           cout<<"ne verno vveli, povtorite vvod - \n";
               cin<<n;
           exit=true;
    }
    else {exit=false;}
}
я только сейчас начал понимать, что я проверяю не посимвольно, а целиком весь num
может кто то сталкивался?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.10.2012, 12:12
Ответы с готовыми решениями:

Проверка на правильность ввода C++
Приветствую Возник вопрос, написал небольшую программку для вычисления корней квадратного уравнения. Проверки все работают. Остается...

Проверка на правильность ввода значения.
Вот пишу так называемую &quot;проверку на дурака&quot;. Столкнулся с проблемой, код: { double ch; int y=0; do{ y=1; int q=0; int...

Проверка на правильность ввода
Добрый день! Задача такова: Ввести число с проверкой; Сравнить их и вывести сообщение. Все хорошо, да после проверки...

30
2 / 2 / 2
Регистрация: 16.10.2012
Сообщений: 69
23.10.2012, 16:29
пробуй функцию atoi();
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
24.10.2012, 05:43
HarryFranc, atoi в случае некорректного аргумента тихо-мирно вернет 0, так что не подходит.

Петр1, можно считывать в строку и разбирать ее содержимое.
1
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
24.10.2012, 05:56
Цитата Сообщение от Nameless One Посмотреть сообщение
можно считывать в строку и разбирать ее содержимое.
А если проверить состояние потока cin после ввода? Ведь если невозможно прочитать данные из потока в переменную типа int, то будет выставлен флаг fail (или bad, в любом случае cin.good()==false)
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
24.10.2012, 06:02
Croessmah, при этом во входном потоке останется мусор, и для того, чтобы последующее чтение прошло корректно, нужно этот мусор убрать, что делается не очень очевидным образом.

А разбирать содержимое строки точно так же методами классов stringstream, проверяя те же выставляемые флаги на предмет ошибки.
0
 Аватар для Петр1
3 / 1 / 0
Регистрация: 09.10.2012
Сообщений: 25
24.10.2012, 12:07  [ТС]
Добрый день!
Вот что получилось:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
exit=true;
while(exit){
    gets(name);
    for(int j=0; name[j]!='\0'; j++){
        if(j>1 || name[j]<'0' || name[j]>'9'){cout<<"povtoritb vvod\n"; exit=true; break;}
        else if(j<2 && name[j+1]=='\0') {
            int n1, n2; 
            if(name[0]!='\0') n1=name[0]; n1=(n1-48)*10;
            if(name[1]!='\0') n2=name[1]; n2-=48;
            ar1[i].day=n1+n2; exit=false;
                }
    }
}
работает, но мне кажется что можно легче сделать, здесь нужно проверять на ввод до 2-х цифр, а дальше мне нужно проверять 4 цифры, после чего еще нужно будет вводить 9 цифр, и самое неприятное эти 9 цифр могут плавать в диапазоне от 5 до 9
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
24.10.2012, 12:27
Не стоит использовать gets. Лучше использовать fgets.

Разбор строки не нужно делать вручную, можно воспользоваться strtod или sscanf:

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
44
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
 
int main(void)
{
    char buf[BUFSIZ];
    char junk;
    int number;
    bool ok = false;
 
    while(!ok)
    {
        fputs("Enter a number: ", stdout);
        fflush(stdout);
 
        if(fgets(buf, BUFSIZ, stdin) == NULL)
        {
            if(!ferror(stdin))
            {
                fputs("No input available\n", stderr);
                exit(EXIT_FAILURE);
            }
            else
            {
                perror("stdin");
                clearerr(stdin);
                continue;
            }
        }
 
        if(sscanf(buf, "%d %c\n", &number, &junk) != 1)
        {
            fputs("Incorrect input\n", stderr);
            continue;
        }
 
        ok = true;
    }
 
    printf("You've entered %d\n", number);
 
    exit(EXIT_SUCCESS);
}
Если использовать C++, а не C, то идея та же. Сначала мы считываем ввод в строку, затем инициализируем этой строкой строковый поток, из которого уже производим чтение числа. Если при чтении не установились флаги ошибки потока, то ввод произошел успешно, в противном случае его нужно повторить.
3
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
24.10.2012, 14:22
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
#include <iostream>
using namespace std;
 
int main() 
{
int n = 0;
while(true)
{
    cout << "Vvedite chislo: ";
    cin >> n;
    if(!cin) 
    {
       cout << "ne verno vveli, povtorite vvod\n";
       cin.clear();
       while (cin.get() != '\n');
    }
    else break;
 }
 
 cout << n << endl;
    
 system("pause");
 return 0;
}
5
 Аватар для Петр1
3 / 1 / 0
Регистрация: 09.10.2012
Сообщений: 25
24.10.2012, 14:36  [ТС]
C
1
2
fputs("Enter a number: ", stdout); // Функция fputs копирует строку, ограниченную нулевым         байтом  в  поток  stream.
fflush(stdout); //Функция fflush записывает в файл содержимое буфера, связанного с потоком stream,
Вот здесь проверка на правильность ввода, что можно ввести чтобы не пройти проверку?
C
1
2
3
4
5
6
7
8
9
10
11
           if(!ferror(stdin))
            {
                fputs("No input available\n", stderr);
                exit(EXIT_FAILURE);
            }
            else
            {
                perror("stdin");
                clearerr(stdin);
                continue;
            }
а как работает эта часть я не понял
Функция sscanf просматривает входные поля, символ за символом.
buf - это то что мы смотрим символ за символом

C
1
2
3
4
5
6
    
    if(sscanf(buf, [COLOR="Red"]"%d %c\n", &number, &junk[/COLOR]) != 1)
        {
            fputs("Incorrect input\n", stderr);
            continue;
        }
0
54 / 54 / 10
Регистрация: 26.09.2011
Сообщений: 186
24.10.2012, 14:58
А чего б не использовать функцию isdigit...
C++
1
2
3
4
5
6
7
8
char ch, mass[20] = {0};
    int res, i = 0;
    while((ch=getch()) != 13) {
        if(isdigit(ch)) mass[i++] = ch;
        else {}
    }
    mass[i] = '\0';
    res = atoi(mass);
Если i = 0 значит ничего не было введено. Как обрабатывать ошибки это другой вопрос и можно как угодно
0
 Аватар для Петр1
3 / 1 / 0
Регистрация: 09.10.2012
Сообщений: 25
24.10.2012, 16:02  [ТС]
Цитата Сообщение от denys_l Посмотреть сообщение
А чего б не использовать функцию isdigit...
угодно
Немного не то, хотя тоже вариант. Дело в том что пользователь должен видеть то что вводит.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
24.10.2012, 16:15
Вот код, который даже не выводит на экран, если это не цифра (или не знак числа перед цифрой):
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "conio.h"
#include "stdio.h"
 
int GetInt()
{
   int k,n=0,flgS=0,c=0,q=0;
 
    while (1)
   {
 
        k=getch();
        
        if ((k == '-') && (c == 0) && (flgS == 0)) 
       {
          flgS=-1;
          putch('-');
          c++;
       }
 
       if ((k >= '0') && (k <= '9')) 
       {
           printf("%c",k);
           n=n*10+k-'0';
           c++;
           q++;
       }
     
       if (k == 8)
       {
           
           putch(8);
           putch(' ');
           putch(8);
           n=n / 10;
           q--;
           if (q < 0) q=0;
           c--;
           if (c < 0) {flgS=0; c = 0;}
       }
 
       if ((k == 13) && (c != 0) && (q != 0)) break;
 
    }
 
    if (flgS == -1) n=-n;
    return n;
}
 
int main(int argc, char* argv[])
{
 
    int m;
 
    m=GetInt();
    printf("\nYou have inputed: %d\n",m);
    getch();
    return 0;
 
}
2
54 / 54 / 10
Регистрация: 26.09.2011
Сообщений: 186
24.10.2012, 16:23
Цитата Сообщение от Петр1 Посмотреть сообщение
Немного не то, хотя тоже вариант. Дело в том что пользователь должен видеть то что вводит.
можно добавить cout << каждый раз при вводе. В любом случае при первой нецифре нас бросит в else. Там можно вывести сообщение о неверном вводе, выйти из цикла, обнулить счетчик, запросить желание набора ещё раз и в случае согласия пробовать ещё
0
 Аватар для Петр1
3 / 1 / 0
Регистрация: 09.10.2012
Сообщений: 25
24.10.2012, 16:25  [ТС]
ого, круто.
подскажите пожалуйста где почтитать про %d %s %c и тд. я не могу понять как этим выражением пользоваться.
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
24.10.2012, 16:29
alsav22, cin.clear по стандарту не очищает входной поток, а всего лишь сбрасывает установленные флаги. Для этого лучше использовать метод ignore, но и у него есть свои недостатки.
0
54 / 54 / 10
Регистрация: 26.09.2011
Сообщений: 186
24.10.2012, 16:30
Цитата Сообщение от Петр1 Посмотреть сообщение
ого, круто.
подскажите пожалуйста где почтитать про %d %s %c и тд. я не могу понять как этим выражением пользоваться.
Прохоренок 1 глава, 18 стр.
Ввод данных в языке С. Это форматированный ввод данных. Токо зачем оно тебе не пойму
1
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
24.10.2012, 16:33
Цитата Сообщение от Nameless One Посмотреть сообщение
alsav22, cin.clear по стандарту не очищает входной поток, а всего лишь сбрасывает установленные флаги. Для этого лучше использовать метод ignore, но и у него есть свои недостатки.
Вы насчёт кода в 8 посте? Так я там cin.clear() и использую для сброса флага ошибки. Очистку потока там это делает:
C++
1
 while (cin.get() != '\n');
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
24.10.2012, 16:34
Цитата Сообщение от Петр1 Посмотреть сообщение
Вот здесь проверка на правильность ввода, что можно ввести чтобы не пройти проверку?
Здесь проверка лишь на то, что ввод строки произошел успешно.

Цитата Сообщение от Петр1 Посмотреть сообщение
а как работает эта часть я не понял
Тут уточняется, что стало причиной неудачного ввода: конец файла или ошибка ввода.



Цитата Сообщение от Петр1 Посмотреть сообщение
Функция sscanf просматривает входные поля, символ за символом.
buf - это то что мы смотрим символ за символом
http://www.opennet.ru/man.shtm... &russian=0

Тут проверяется, что в введенной строке содержится именно число и что после этого числа нет никакого «мусора». Ну и параллельно считывается это число из строки.
1
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
24.10.2012, 16:36
Вот ещё один вариант того же:
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//Вводятся только числа.
 
#include "conio.h" // для getch().
#include <iostream>
#include <string>
#include <sstream> // для stringstream.
using namespace std;
 
int main()
{
  int n = 0, flgS = 0, c = 0, q = 0; 
  unsigned char k = 'a'; // переменная для ввода.
  string str;      // строка для цифр и минуса.
 
 
   
    while (k != '|')
   {
        k = getch(); // ввод без отображения.
        if (k == '|') break;
        
        if ((k == '-') && (c == 0) && (flgS == 0)) // если символ минус, и число символов 0, 
                                                   //и минус ни разу не отображался (флаг 0).
       {
          flgS=-1; // если отображается минус.
          cout << '-';      // отображаем минус.
          str.push_back(k); // минус помещаем в строку.
          c++;              // число символов.
       }
        
        if ((k >= '0') && (k <= '9')) // если символ цифра.
       {
           cout << k;        // отображаем цифру.
           str.push_back(k); // символ в строку.
           c++;              // число символов.
           q++;              // число цифр.
       }
     
       if (k == '\b' && c != 0) // если backspace и число символов не 0.
       {
           cout << '\b'; // курсор на шаг назад.
           cout << ' ';  // затираем последий символ.
           cout << '\b'; // курсор на шаг назад.
           if (!str.empty()) // если строка не пуста, 
              str.pop_back(); // то извлекаем один.
           q--;            // число цифр уменьшили.
           if (q < 0) q = 0; // если получили отрицательное значение, то делаем 0. 
           c--;            // число символов уменьшили.
           if (c <= 0)     // если удалённый символ был последним,
           {
                flgS = 0; // обнуляем флаг, чтобы можно было снова отображать минус.
                c = 0;    // количество символов 0.
           } 
       }
 
       if ((k == 13) && (c != 0) && (q != 0)) break; // если, хотя бы, одна цифра введена, то выход. 
 
    }
    stringstream stream(stringstream::in | stringstream::out); // создаётся объект для внутреннего форматирования.
    stream << str; // вводим строку числовых символов.
    stream >> n;   // извлекаем число.
    cout << endl << n << endl;
 
 system("pause");
 return 0;  
}
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
24.10.2012, 16:44
Цитата Сообщение от alsav22 Посмотреть сообщение
Вы насчёт кода в 8 посте? Так я там cin.clear() и использую для сброса флага ошибки. Очистку потока там это делает:
Попробуй просто нажать на Enter.

Добавлено через 4 минуты
Вот очень хорошая статья про то, какими способами можно очищать входной поток, и почему эти способы часто не работают.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.10.2012, 16:44
Помогаю со студенческими работами здесь

Проверка на правильность ввода
Всем привет. Есть такая проблема - у меня есть код с готовым решением, но к нему не хватает маленькой проверки, которая будет зацикливаться...

Проверка StringGrid на правильность ввода
Здравствуйте, СРОЧНО нужна помощь. Нужна проверка на любые символы кроме цифр в таблице стрингрид. (т.е. при нажатии на кнопку...

Проверка на правильность ввода текста
Здравствуйте, такой вопрос как сделать проверку текста. Совпадает ли имя которое ввел пользователь с именем которое было в строке? ...

Проверка на правильность ввода юзером данных в TextBox
есть два текстбокса, три кнопки - регистрация (заносит данные в текстовик), логин, выход есть документ.txt, в котором 2 строки, первая -...

Проверка ввода с клавиатуры
Скажите, в Хаскеле есть стандартные функции проверки ввода с клавиатуры(как kbhit в C или keypressed в паскале)? З.Ы. я под Линуксом.


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью в КА2. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа в КА2. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru