2011-10-30 11 views
5

Próbuję napisać funkcję, która monituje użytkownika o pięciocyfrowy numer, i chcę napisać blok wyjątków, aby obsłużyć złe wejście, gdy użytkownik próbuje wprowadzić ciąg znaków lub niektóre niecałkowite dane wejściowe.Jak napisać obsługę wyjątków dla błędnych danych wejściowych?

Wiem, jak napisać blok obsługi wyjątków dla czegoś takiego jak funkcja dzielenia, w której wyrzucono wyjątek dla mianownika o wartości 0, ale nie mam pojęcia, jak to zrobić dla danych wejściowych, na które nie mam wpływu.

Odpowiedz

7

Przede wszystkim generalnie odradzam to - złe dane wejściowe od użytkownika są prawie regułą, a nie wyjątkiem.

Jeśli domagać się robi to tak, że prawdopodobnie to zrobić przyjmując cokolwiek jako wejście, a następnie rzuca wyjątek, kiedy/jeśli to nie jest to, co chcesz:

// Warning: untested code.  
// Accepting negative numbers left as an exercise for the reader. 
int get_int(std::istream &is) { 
    std::string temp; 

    std::getline(temp, is); 

    for (int i=0; i<temp.size(); i++) 
     if (!isdigit(temp[i])) 
      throw std::domain_error("Bad input"); 
    return atoi(temp); 
} 

powtarzam, jednak uważam, że nie jest to ogólnie dobry pomysł. Zauważyłem (na przykład), że iostreams definiują już bit fail specjalnie dla takich sytuacji (i normalny operator>> odczytanie int używa tego mechanizmu).

+0

Używasz 'atoi()', ale wciąż sprawdzaj każdy znak twojego łańcucha pod kątem innych cyfr. Czemu?? – vsz

+0

Dziękuję. Z jakiegoś powodu utknęłam w nastawieniu, że moje wejście musiało być przechowywane w zmiennej liczbowej. Akceptowanie danych wejściowych jako ciągu znaków, a następnie ich konwertowanie rozwiązuje mój problem. – JeramyRR

+0

@vsz: Jego pytanie dotyczyło w szczególności sprawdzenia złych danych wejściowych i wyrzucenia wyjątku, gdy został napotkany. Zrobiwszy to, 'atoi' był najszybszym i najłatwiejszym sposobem zwracania int. –

0

Najprostszym rozwiązaniem jest odczytanie ciągu znaków i przekonwertowanie go na liczbę całkowitą, na przykład za pomocą atoi. Jeśli otrzymasz zero jako wynik, a twój ciąg nie będzie miał wartości "0", wiesz, że dane wejściowe nie były liczbowe, bez potrzeby przechodzenia przez pętlę przez siebie.

+0

Niestety muszę użyć 0, aby zakończyć część wejściową programu, więc muszę wiedzieć, kiedy wejście jest naprawdę 0. – JeramyRR

+0

Możesz sprawdzić osobno, czy wejście jest naprawdę 0, czy nie. Bardziej szczegółową dyskusję można znaleźć na stronie http://stackoverflow.com/questions/1640720/how-do-i-tell-if-the-c-function-atoi-failed-or-if-it-wasa-a- ciąg zer – vsz

0

Wyjątki są często odpowiednie w przypadku akceptowania danych z innego komputera lub procesu, gdy nie ma powodu, aby oczekiwać nieprawidłowych danych w prawidłowym strumieniu danych. W odniesieniu do danych wprowadzanych przez użytkownika wyjątki powinny być stosowane tylko w przypadkach, które powinny wyraźnie odbiegać od normalnego przebiegu programu. Na przykład, jeśli program ma interfejs w stylu tty, a procedura, która ma odczytać linię wejścia, uzyskuje kontrolkę C, to może być użyteczne dla takiej procedury zgłoszenie wyjątku. Sterowanie C nie powinno koniecznie kończyć programu, ale jeśli program spodziewa się odczytać kilka linii danych wejściowych od użytkownika, wpisanie control-C na jednym powinno często powodować pominięcie reszty.

Powiązane problemy