Problem z cin

mam taki problem. chce zabezpieczyć funkcje cin>>int przed wprowadzeniem danych innego typu. mianowicie chce żeby po wpisaniu przez użytkownika jakiegoś znaku np litery program kazał wpisać liczbe od nowa. próbowałem wiele razy i za każdym po wpisaniu liczby innego typu niz int lub jakiegos znaku program sie blokuje. wiem że chodzi o strumien ale nie za bardzo potrafie tak zrobić by po takim błedzie odblokowac ten strumien. z góry dziękuje za pomoc

#include 

using namespace std;


int main()


{

char wybor='t';

      int ktory;

      cout<<"Kamil Borowki\nProgram testujacy strukture klas liczby zespolone i zbiory liczb zespolonych\n";

      cout<<"\n 1-dzialania na liczbach zespolonych\n2-dzialania na zbiorach zespolonych\n";

      while(wybor=='t')

      {

                      cin>>ktory;


                     switch(ktory)

                      {

                                   case 1:

                                   cout<<"wybrales dzialania na liczbach";

                                   wybor='n';

                                   break;


                                   case 2:

                                   cout<<"wybrales dzialania na zbiorach";

                                   wybor='n';

                                   break;


                                   default:

                                   cout<<"wpisz 1 lub 2";

                                   break;

                                   }


                                      }

system("PAUSE");

  return 0;

}

Złączono Posta : 03.11.2007 (Sob) 15:10

sorry

nie wiem jakim cudem 2x ten sam temat wkleilem. prosze o skasowanie

To może Ci się przydać: http://www.cppreference.com/stdstring/isdigit.html

Spróbuj zastosować wyjątki (try i catch). To powinno pomóc.

Musisz używać do tego cin?

Mialem ten sam problem i znalazlem takie cudo:

if (cin.fail()) Oczywiscie if zaraz po operacji cin i najlepiej komunikat wyswietlic w wyjaku ;) Albo warunek uzyc w petli while co zmusi do podania poprawnych danych :)

sposob jaki zaproponowal Mifczu jest bardzo zgrabny. ja robilem kiedys cos takiego:

void read_int(int& i)

{

   for ( ; ; cout << "Sprobuj jeszcze raz\n")

   {

       string buf;


       if (!getline(cin, buf))

          return 0;


       char* stop;

       long l = strtol(buf.c_str(), &stop, 10);


       if (*stop || (stop == buf))

          continue;


       i = (int)l;


       break;

   }

}

moze naokolo ale dzialalo bardzo ladnie :smiley:

Użyj szukajki - było na forum już nie raz. Jeśli chcesz sprawdzić poprawność danych, powinieneś wczytać ciąg znaków i dokonać konwersji.

Kiedyś napisałem coś takiego: (funkcja nie reaguje na inne klawisze niż liczby w tym (ujemne i dodatnie))

//Coded by Derka

#include 

#include 

using namespace std;


void getnum( int &wsp);

int a;


int main()

{



    getnum(a);

    cout<<"\nWartosc a: "<
     

 getch();   

 return 0;   

}  


void getnum( int &wsp)

{     

       char zn; int cntr=0; char array [50]; char * num=array;


   do { 

       zn=getch(); if ((zn>='0' && zn<='9') || (zn=='-' && cntr==0) || (zn=='+' && cntr==0)) 

       {cout<<(*num=zn); num++; cntr++;} 

       else if(zn=='\b' && cntr!=0) { cout<<"\b \b"; num--; cntr--;}  

      }while (zn!=13 && cntr<50);

      if (cntr==0 && zn==13) cout<<0;

      *num='\0'; wsp=(atoi(num-cntr));   

}

[/code]

Myślę iż nie ma sensu męczyć użytkownika komunikatami typu

Uwaga źle podałeś liczbe. Lepszym rozwiązaniem jest zablokowanie innych znaków niż dopuszczalne.

@Derka: Skoro i tak czytasz znako po znaku to tablica jest Ci zupełnie zbędna. Poza tym getch() nie bez powodu zwraca inta a nie chara. Nie bardzo też wiem czemu a jest zadeklarowane jako zmienna globalna. Poza tym dobrze byłoby wyzerować array przy inicjalizacji ( = {0}; ).

@Ryan. Kod może jest mało optymalny bo pisany już jakiś czas temu. Tablicy nie zerowałem ponieważ zawsze dorzucam znak NULL co załatwia mi sprawę śmieci w dalszych elementach tablicy. A tablicy używam żeby przechowywać liczby np jak user wprowadzi 9555645645 jakoś nie widze innego sposobu aby przechowywac wieksze liczby niz 1 cyfrowa gdy pobieram je getch();. Co do zmiennej globalnej a to czysty przypadek z reguły deklaruje je wew. main() tu wrzuciłem ją jako globalną ze względu na czytelność. Jeśli masz pomysł na zaoptymalizowaną wersje tej funkcji chętnie ją poznam.

I tak i nie. Częściowo załatwia Ci sprawę przepełnienia bufora o jeden (bardzo częsty błąd). Pytanie: czemu nie skorzystać z zerowania “za darmo”? Zerowanie wszystkich zmiennych przy deklaracji jest w ogóle dobrym nawykiem. :slight_smile:

Bo źle podchodzisz do problemu. Nie chodzi o to, żeby przechowywać ciąg, tylko żeby go w locie konwertować na liczbę. Jest to znacznie korzystniejsze rozwiązanie.