[C++] Zabezpieczanie przed literami


(Artur520) #1

Napisał program, który liczy średnią i potem są na niej wykonywane różne operacje. Mało ważne. Chce go zabezpieczyć przed wprowadzaniem innych liczb, niż ja sobie tego życzę oraz przed literami. I tu zaczyna się problem.

Liczby zabezpieczone są okej. Wszystko działa. Program omija złą liczbę i prosi jeszcze raz o nią. Gdy jednak wprowadzi się literę przechodzi on dalej. Tak jakbym wprowadził 0(jest ono odpowiedzialne za zakończenie wprowadzania kolejnych liczb i przejście do operacji właściwych). nX to współrzędna "y" do wyświetlania tekstu, żeby nie było "zagwostki" .

do

	{ // do while

	gotoxy(24,nX);

	cout<<"Podaj ocene nr " << nr << ": " ;

		cin>>ocena;


	if ((ocena !=2 ) && (ocena !=3 ) && (ocena !=3.5 ) && (ocena !=4 ) && (ocena !=4.5 ) && (ocena !=5 ) && (ocena !=0 ))

	{ // if warunek liczbowy

	cprintf("\n\t\t BLAD, zla ocena\n");

	cprintf("\t\t Podaj ocene jeszcze raz\n");

	nX =nX+5;


	} // if warunek liczbowy

	else if(cin.fail()) 

      { // if warunek literowy

         cout << "Blad" << endl; 

         cin.clear(); 

         cin.ignore(INT_MAX,'\n'); 

         cin.ignore(); 

      } // if warunek literowy


	else

	if(ocena>0)

	{ // if srednia

		srednia +=ocena;

		ilosc +=1;

		nX +=1;

		nr++;

	} // if wewnetrzny zamykajcy 


} // do while zamykajacy 

	while (ocena != 0);

		if(ilosc>0) srednia /=ilosc;

		gotoxy(20,2+nX);

(Sawyer47) #2

Z tego co pamiętam można zrobić

if(cin >> ocena) {

  // ok

} else {

 // not ok

}

Jest zapewne jakaś odpowiadająca metoda obiektu cin, żeby nie musieć pisać pobierania w warunku, ale nie pamiętam która.


(Artur520) #3

Nic nie zrozumiałem z tego co napisałeś.

w tym if przecież tylko tak jakby wprowadzimy wartość cin ;/ no i co dalej? Jeśli wprowadzimy to wykona się coś tam, jeśli nie wprowadzimy ( a wprowadzić trzeba) to się nie wykona. Albo czegoś kompletnie nie rozumiem.


(etam) #4

Spróbuj tego: wczytać z wejścia do stringa (łyka wszystko), potem z tego stringa do stringstreamu i z tego do zmiennej. Poprawność operacji sprawdzasz http://en.cppreference.com/w/cpp/io/basic_ios/good (stringstream dziedziczy tą metodę po basic_ios).


#5

Ewentualnie pobierz do chara i sprawdź czy wartość ascii odpowiada kodom cyfr, później odejmij odpowiednią wartość (48) i przypisz do integera jako liczba.


(system) #6

Naprawdę komplikujecie sprawę ... :slight_smile:

if ((ocena !=2 ) && (ocena !=3 ) && (ocena !=3.5 ) && (ocena !=4 ) && (ocena !=4.5 ) && (ocena !=5 ) && (ocena !=0 ))

Nie lepiej zrobić

const unsigned int r = 5;

.......

double tab[r] = {2.0,3.0,3.5,4.5,5.0,0.0};

i teraz tak :

int * fx = new int;

do {

  cin >> liczba;

  for(unsigned int i = 0; i < r; ++i){

     if(liczba == tab[i])

         *fx = 1;

     else

         *fx = 0;

  }

} while((*fx) != 0);

delete fx;

Oczywiście liczbę można zmienić na tablicę i dodać sobie zmienną, która będzie inkrementować indeks tablicy. Piszę bez kompilatora, ale powinno to zadziałać zamierzenie też powinno być raczej podobne. A, jeżeli ktoś wcisnął 'a' i zatwierdził a mamy zmienną typu liczbowego, to można to wyłączyć poprzez

if(!cin)

i wstawić koniunkcję w while