Wprowadzanie tylko liczb - język C

0

Cześć, jestem początkująca w programowaniu i piszę obecnie kalkulator i chcę, go zabezpieczyć przed wprowadzaniem liter z klawiatury. Chcę żeby wpisywane były same liczby. Czy w języku C istnieje funkcja albo algorytm, która zablokuje wprowadzanie liter? Albo poprosi użytkownika o ponowne wpisanie danych w przypadku wpisania liter. NIe mogę sobie z tym poradzić, dlatego proszę o pomoc

8

Zabezpieczenie przed wpisywaniem liter

Teraz widzę, że dla C ten FAQ wymaga poprawki. Może zrobię to wieczorem.

0
#include <stdio.h>

int main()
{
	int x;
	for(;;)
	{
		printf("podaj liczbe: ");
		if(scanf("%d",&x)==1) printf("Podano liczbe %d\n",x); // wprowdzna 1 zmienna
		else // nie udało się wprowadzic 
		{
		     //*/// wywalamy do dowolnego białego znaku
			 while(!isspace(getchar())) {}
             /*/// ewentualnie zamiast ... wywalamy do entera
		     while(getchar()!='\n') {}
		     //*///
		     printf("Prosze podacz liczbe.\n");
		}
	}
	return 0;
}

Z tym że w przypadku kalkulatora lepiej od razu całe wyrażenie podawać:

#include <stdio.h>

typedef double opr(double a,double b);
double add(double a,double b) { return a+b; }
double sub(double a,double b) { return a-b; }
double mul(double a,double b) { return a*b; }
double div(double a,double b) { return a/b; }

struct { char op; opr *calculate; } tb[]=
{
	{'+',&add},
	{'-',&sub},
	{'*',&mul},
	{'/',&div},
};

int main()
{
	for(;;)
	{
		double a,b;
		char op;
		printf("podaj wyrażenie (np 10 + 3): ");
		if(scanf("%lf %c %lf",&a,&op,&b)==3) // wprowdzna 3 zmiennych
		{
			for(int i=0;i<sizeof(tb)/sizeof(*tb);++i)
			{
				if(op==tb[i].op)
				{
					printf("%lf %c %lf = %lf\n",a,op,b,tb[i].calculate(a,b));
					op=0;
				}
			}
			if(op) printf("Nieznana operacja: '%c'\n",op);
		}
		else // nie udało się wprowadzic 
		{
		     printf("Niepoprawne wyrazenie.\n");
		     while(getchar()!='\n') {}
		}
	}
	return 0;
}
1

Zabezpieczenie przed wprowadzaniem liter brzmi jakby tylko cyfry miały działać, a wciśnięcie liter nie powodowało wpisania litery. W standardzie nie ma na to sposobu. Jeśli o konsolę chodzi to na windowsie jest conio.h dostępne. Na linuksie dosyć zawiłe to jest z tym ioctl bardzo brzydka sprawa i bardzo nieprzyjemna jak taki program ci się sypnie. Na szczęście jest bibioteka ncurses, od razu będzie też na windę przenośne. Wtedy czytasz po znaku i za każdym razem sprawdzasz czy znak ci pasuje, a jak nie to ignorujesz. Podobnie w aplikacjach okienkowych, chyba że masz kontrolkę specjalnie dedykowaną liczbom.
Co innego walidacja, sprawdzanie poprawności. Wystarczy użyć scanf (lub fscanf jeśli chcemy z pliku czytać lub strumienia), jak zwraca liczbę elementów podanych do wczytania to znaczy, że jest dobrze. :)

0

Wiersja 1:

#include <iostream>
using namespace std;

typedef double opr(double a,double b);
double add(double a,double b) { return a+b; }
double sub(double a,double b) { return a-b; }
double mul(double a,double b) { return a*b; }
double div(double a,double b) { return a/b; }

struct { char op; opr *calculate; } tb[]=
{
    {'+',&add},
    {'-',&sub},
    {'*',&mul},
    {'/',&div},
};

int main()
{
    for(;;)
    {
        double a,b;
        char op;
        cout<<"podaj wyrażenie (np 10 + 3): ";
        if(cin>>a>>op>>b)
        {
            for(int i=0;i<sizeof(tb)/sizeof(*tb);++i)
            {
                if(op==tb[i].op)
                {
                    cout<<a<<' '<<op<<' '<<b<<" = "<<tb[i].calculate(a,b)<<endl;
                    op=0;
                }
            }
            if(op) cout<<"Nieznana operacja: "<<op<<endl;
        }
        else
        {
             cout<<"Niepoprawne wyrazenie."<<endl;
             cin.clear(ios::goodbit);
             while(cin.get()!='\n') {}
        }
    }
    return 0;
}

Wiersja 2

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	typedef double Function(double a,double b);
	struct Operation { char op; Function *calculate; };
	static vector<Operation> tb 
	{
	    {'+',[](double a,double b){ return a+b; }},
	    {'-',[](double a,double b){ return a-b; }},
	    {'*',[](double a,double b){ return a*b; }},
	    {'/',[](double a,double b){ return a/b; }},
	};
    for(;;)
    {
        double a,b;
        char op;
        cout<<"podaj wyrażenie (np 10 + 3): ";
        if(cin>>a>>op>>b)
        {
            for(int i=0;i<tb.size();++i)
            {
                if(op==tb[i].op)
                {
                    cout<<a<<' '<<op<<' '<<b<<" = "<<tb[i].calculate(a,b)<<endl;
                    op=0;
                }
            }
            if(op) cout<<"Nieznana operacja: "<<op<<endl;
        }
        else
        {
             cout<<"Niepoprawne wyrazenie."<<endl;
             cin.clear(ios::goodbit);
             while(cin.get()!='\n') {}
        }
    }
    return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1