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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 118, средняя оценка - 4.87
Петр1
 Аватар для Петр1
3 / 1 / 1
Регистрация: 09.10.2012
Сообщений: 25
23.10.2012, 12:12     Проверка на правильность ввода с клавиатуры #1
Здравствуйте!
задача: пользователь вводит с клавиатуры цифру, нужно проверить что пользователь действительно ввел цифру, а не букву, знак или сочетание вышесказанного (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
может кто то сталкивался?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.10.2012, 12:12     Проверка на правильность ввода с клавиатуры
Посмотрите здесь:

C++ проверка кода на правильность
Проверка на правильность ввода значения. C++
Проверка e-mail на правильность. C++
C++ Проверка на правильность кода
C++ Как контролировать правильность ввода?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
HarryFranc
2 / 2 / 2
Регистрация: 16.10.2012
Сообщений: 69
23.10.2012, 16:29     Проверка на правильность ввода с клавиатуры #2
пробуй функцию atoi();
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.10.2012, 05:43     Проверка на правильность ввода с клавиатуры #3
HarryFranc, atoi в случае некорректного аргумента тихо-мирно вернет 0, так что не подходит.

Петр1, можно считывать в строку и разбирать ее содержимое.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
24.10.2012, 05:56     Проверка на правильность ввода с клавиатуры #4
Цитата Сообщение от Nameless One Посмотреть сообщение
можно считывать в строку и разбирать ее содержимое.
А если проверить состояние потока cin после ввода? Ведь если невозможно прочитать данные из потока в переменную типа int, то будет выставлен флаг fail (или bad, в любом случае cin.good()==false)
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.10.2012, 06:02     Проверка на правильность ввода с клавиатуры #5
Croessmah, при этом во входном потоке останется мусор, и для того, чтобы последующее чтение прошло корректно, нужно этот мусор убрать, что делается не очень очевидным образом.

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

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
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.10.2012, 12:27     Проверка на правильность ввода с клавиатуры #7
Не стоит использовать 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, то идея та же. Сначала мы считываем ввод в строку, затем инициализируем этой строкой строковый поток, из которого уже производим чтение числа. Если при чтении не установились флаги ошибки потока, то ввод произошел успешно, в противном случае его нужно повторить.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.10.2012, 14:22     Проверка на правильность ввода с клавиатуры #8
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;
}
Петр1
 Аватар для Петр1
3 / 1 / 1
Регистрация: 09.10.2012
Сообщений: 25
24.10.2012, 14:36  [ТС]     Проверка на правильность ввода с клавиатуры #9
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;
        }
denys_l
51 / 51 / 4
Регистрация: 26.09.2011
Сообщений: 186
24.10.2012, 14:58     Проверка на правильность ввода с клавиатуры #10
А чего б не использовать функцию 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 значит ничего не было введено. Как обрабатывать ошибки это другой вопрос и можно как угодно
Петр1
 Аватар для Петр1
3 / 1 / 1
Регистрация: 09.10.2012
Сообщений: 25
24.10.2012, 16:02  [ТС]     Проверка на правильность ввода с клавиатуры #11
Цитата Сообщение от denys_l Посмотреть сообщение
А чего б не использовать функцию isdigit...
угодно
Немного не то, хотя тоже вариант. Дело в том что пользователь должен видеть то что вводит.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.10.2012, 16:15     Проверка на правильность ввода с клавиатуры #12
Вот код, который даже не выводит на экран, если это не цифра (или не знак числа перед цифрой):
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;
 
}
denys_l
51 / 51 / 4
Регистрация: 26.09.2011
Сообщений: 186
24.10.2012, 16:23     Проверка на правильность ввода с клавиатуры #13
Цитата Сообщение от Петр1 Посмотреть сообщение
Немного не то, хотя тоже вариант. Дело в том что пользователь должен видеть то что вводит.
можно добавить cout << каждый раз при вводе. В любом случае при первой нецифре нас бросит в else. Там можно вывести сообщение о неверном вводе, выйти из цикла, обнулить счетчик, запросить желание набора ещё раз и в случае согласия пробовать ещё
Петр1
 Аватар для Петр1
3 / 1 / 1
Регистрация: 09.10.2012
Сообщений: 25
24.10.2012, 16:25  [ТС]     Проверка на правильность ввода с клавиатуры #14
ого, круто.
подскажите пожалуйста где почтитать про %d %s %c и тд. я не могу понять как этим выражением пользоваться.
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.10.2012, 16:29     Проверка на правильность ввода с клавиатуры #15
alsav22, cin.clear по стандарту не очищает входной поток, а всего лишь сбрасывает установленные флаги. Для этого лучше использовать метод ignore, но и у него есть свои недостатки.
denys_l
51 / 51 / 4
Регистрация: 26.09.2011
Сообщений: 186
24.10.2012, 16:30     Проверка на правильность ввода с клавиатуры #16
Цитата Сообщение от Петр1 Посмотреть сообщение
ого, круто.
подскажите пожалуйста где почтитать про %d %s %c и тд. я не могу понять как этим выражением пользоваться.
Прохоренок 1 глава, 18 стр.
Ввод данных в языке С. Это форматированный ввод данных. Токо зачем оно тебе не пойму
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.10.2012, 16:33     Проверка на правильность ввода с клавиатуры #17
Цитата Сообщение от Nameless One Посмотреть сообщение
alsav22, cin.clear по стандарту не очищает входной поток, а всего лишь сбрасывает установленные флаги. Для этого лучше использовать метод ignore, но и у него есть свои недостатки.
Вы насчёт кода в 8 посте? Так я там cin.clear() и использую для сброса флага ошибки. Очистку потока там это делает:
C++
1
 while (cin.get() != '\n');
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.10.2012, 16:34     Проверка на правильность ввода с клавиатуры #18
Цитата Сообщение от Петр1 Посмотреть сообщение
Вот здесь проверка на правильность ввода, что можно ввести чтобы не пройти проверку?
Здесь проверка лишь на то, что ввод строки произошел успешно.

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



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

Тут проверяется, что в введенной строке содержится именно число и что после этого числа нет никакого «мусора». Ну и параллельно считывается это число из строки.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
24.10.2012, 16:36     Проверка на правильность ввода с клавиатуры #19
Вот ещё один вариант того же:
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;  
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.10.2012, 16:44     Проверка на правильность ввода с клавиатуры
Еще ссылки по теме:

циклические алгоритмы (проверять правильность ввода данных) C++
C++ Правильность ввода даты
Ввод и проверка на правильность пароля C++

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

Или воспользуйтесь поиском по форуму:
Nameless One
Эксперт С++
 Аватар для Nameless One
5755 / 3404 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
24.10.2012, 16:44     Проверка на правильность ввода с клавиатуры #20
Цитата Сообщение от alsav22 Посмотреть сообщение
Вы насчёт кода в 8 посте? Так я там cin.clear() и использую для сброса флага ошибки. Очистку потока там это делает:
Попробуй просто нажать на Enter.

Добавлено через 4 минуты
Вот очень хорошая статья про то, какими способами можно очищать входной поток, и почему эти способы часто не работают.
Yandex
Объявления
24.10.2012, 16:44     Проверка на правильность ввода с клавиатуры
Ответ Создать тему
Опции темы

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