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

- Rejestracja:około 17 lat
- Ostatnio:minuta
Zabezpieczenie przed wpisywaniem liter
Teraz widzę, że dla C ten FAQ wymaga poprawki. Może zrobię to wieczorem.

- Rejestracja:ponad 19 lat
- Ostatnio:3 miesiące
#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;
}

- Rejestracja:ponad 18 lat
- Ostatnio:około 18 godzin
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. :)

- Rejestracja:ponad 19 lat
- Ostatnio:3 miesiące
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;
}
{'%',[](double a,double b){ return fmod(a,b); }},
po wierszu 10...14 (do wyboru) aby pojawiła się dodatkowa operacja '%'.