• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Walidacja danych wejsciowych .

Object Storage Arubacloud
0 głosów
2,254 wizyt
pytanie zadane 12 maja 2018 w C i C++ przez qlucha Obywatel (1,790 p.)
edycja 12 maja 2018 przez qlucha

Prośba o ocenę kodu . Walidacja danych wejsciowych dla liczb całkowitych. Czy to dobre rozwiązanie ?

// Walidacja danych wejsciowych czy to Liczba
    string liczbaString;
    int liczbaTypuInt, dlugosc;
    bool czyToLiczba ;

    do{
        czyToLiczba = true;
        cout << "Podaj Liczbe :";
        cin >> liczbaString;

        for (int i = (dlugosc = (liczbaString.length())-1); i >= 0; i--) {


            if ((liczbaString[i] < 48) || (liczbaString[i] > 57)) {

                cout << "To nie jest liczba. Wprowadz jeszce raz." <<'\n';
                czyToLiczba = false;
                break;
            }
        }
    }while(czyToLiczba == 0);
    
    //Konwersja string na intiger
    liczbaTypuInt = atoi(liczbaString.c_str());
    cout << liczbaTypuInt <<endl;
//Koniec walidacji czy to liczba

 

komentarz 12 maja 2018 przez monika90 Pasjonat (22,940 p.)
A jak wpiszę -7, to co? I dlaczego tam jest jakieś 48 i 57, czy tak trudno napisać '0' i '9'?
komentarz 12 maja 2018 przez j23 Mędrzec (194,920 p.)

@qlucha,

A to nie prościej tak:

cout << "Podaj Liczbe :";
cin >> liczbaTypuInt;
if(cin.fail())
{
	cout << "Shieeet!!!1\n";
}

 

komentarz 12 maja 2018 przez qlucha Obywatel (1,790 p.)
Ciekawa uwaga z liczbą ujemną , Ale ta walidacja była robiona dla liczb dodatnich , pod wybor danej opcji z menu . A w menu nie ma opcji wyboru liczby ujemnej. (nie napisałem o tym).

A te liczby to przedział z tablicy ASCII. Jest to zmienna string a w zmiennej string liczba 9 nie odpowiada liczbie 9 tylko decymalnie jest zapisana w stringu jako liczba  57
komentarz 12 maja 2018 przez qlucha Obywatel (1,790 p.)

Dzieki za odpowiedz. O wiele prościej. smileyyes .

Ja nie jestem profesjonalnym programistą komputerowym , uczę się wszystkich wątków w c++ jak na razie , jak działają ,pętle , intrukcje warunkowe, switch,, jak zbudowany jest string , tablice jedno i wielowymiarowe  itp. itd. Jest tego sporo .

Im wiecej dobrych rad tym lepiej :)) 

(czasami pisanie takiego rozpasanego kodu pomaga utrwalic wiedzę jak to wszystko działa i się uzupełnia aby w przyszłości wybrać proste i najlepsze rozwiązania )enlightenedwink

1 odpowiedź

+1 głos
odpowiedź 12 maja 2018 przez niezalogowany
edycja 14 maja 2018

Zazwyczaj nie trzeba znać kodów ASCII każdego znaku:

if ((liczbaString[i] < '0') || (liczbaString[i] > '9')) {

W cctype jest wiele funkcji sprawdzających czy dany znak jest cyfrą, małą literą, dużą literą etc:

if (std::isdigit(liczbaString[i])) { // zwróci true badź false

Można sobie zmniejszyć ryzyko pomyłki znaku czy kodu ascii ;)

Jeżeli wymagasz tylko liczby dodatnie można też zrobić to tak:

#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>

int main() {
	std::string str;
	do {
		std::cout << "Podaj łańcuch znaków reprezentujący liczbę naturalną: ";
		std::cin >> str;
	} while (!std::all_of(str.begin(), str.end(), [](unsigned char i) { return std::isdigit(i); } )); // tak długo jak każdy element str nie będzie cyfrą
	std::cout << "Podano: " << str << "\n";
}

Jeżeli nie to łap inne przykłady na przyszłość:)

#include <iostream>
#include <limits>

int main() {
	std::cout << "Podaj liczbę: ";
	int number;
	while (!(std::cin >> number))
	{
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
		std::cerr << "Podano nieprawidłową wartość typu int.\n"
			<< "Spróbuj jeszcze raz: ";
	}
	std::cout << "Udało się wczytać: " << number << "\n";
}

Włącz w swoim kompilatorze C++11. Chociaż dla wygodnych konwersji string -> int(std::to_string), int -> string(std::stoi - rzuca wyjątek gdy nie będzie możliwa konwersja) itp. Przykład:

#include <iostream>
#include <string>

int main() {
	std::string inputs[6] =
	{
		"ala ma kota",
		"asdgff7892345",
		"8577890asdf",
		"3425724389057234890570892358",
		"-1",
		"-1234.234"
	};

	for (int i = 0; i < 6; ++i) {
		int number;
		std::cout << "|" << inputs[i] << "|";

		try {
			number = std::stoi(inputs[i]);
			std::cout << " zamieniono na liczbę |" << number << "|\n";
		} catch (...) {
			std::cout << " - nie można zamienić.\n";
		}
	}
}
komentarz 13 maja 2018 przez qlucha Obywatel (1,790 p.)

Jeszcze jeden przykład , bardzo prosty prosiłbym o wyjaśnienie :

zastanawiam się dlaczego cin.ignore(); nie działa .

przykład ; wprowadz 55aa  i program się wysypie przy zapisie do zmiennej string imie.

#include <iostream>

using namespace std;

int main()
{
    int liczbaTypuInt;
    cout << "Podaj Liczbe :";

    cin >> liczbaTypuInt;
    if(cin.fail())
        {
        cout << "Shieeet!!!1 " <<'\n';
    }

    cin.ignore();
    string Imie;
    cout << liczbaTypuInt << endl;
    cout << "Wprowadz imie :" ;
    cin >> Imie;
    cout << Imie << endl;

    return 0;
}

 

komentarz 13 maja 2018 przez niezalogowany

Sam domyślna ilość znaków odrzucona przez cin.ignore to 1. Gdy wpiszesz '55aa' to jedno 'a' zostanie odrzucone drugie nadal pozostanie w strumieniu i zostanie automatycznie wczytane przy kolejnym cin. Więc trzeba wpisać ile znaków ma zostać odrzuconych (np cały rozmiar strumienia).

PS. Teraz widzę, że do numeric_limits zapomniałem dodać nagłówek <limits>.

komentarz 13 maja 2018 przez qlucha Obywatel (1,790 p.)
gdy podam jako argument aby zignorować 10 znaków , cin.ignore(10);

Zawiesza mi program myśli bardzo długo i nic sie nie dzieje na ekranie , nie wiem czemu .

Czy mógłbyś podać także argument ,który kasuje wszystkie znaki w buforze .
komentarz 13 maja 2018 przez niezalogowany
edycja 13 maja 2018
#include <iostream>
#include <limits>
#include <string>

using namespace std;

int main()
{
    int liczbaTypuInt;
    cout << "Podaj Liczbe :";
    cin >> liczbaTypuInt;
    if (cin.fail())
    {
        cout << "Shieeet!!!1 " << '\n';
        cin.clear();
    }
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    string Imie;
    cout << liczbaTypuInt << endl;
    cout << "Wprowadz imie :";
    cin >> Imie;
    cout << Imie << endl;

    return 0;
}
komentarz 13 maja 2018 przez qlucha Obywatel (1,790 p.)
nie wiem czemu ale u mnie nie działa , efekt jest ten sam co poprzednio po wprowadzeniu 55aa
komentarz 13 maja 2018 przez niezalogowany
Już wiem dla przypadku 55aa liczba zostaje wczytana, więc nie ma błędu (fail), ale 'aa' zostaje w strumieniu.
komentarz 14 maja 2018 przez monika90 Pasjonat (22,940 p.)
źle używasz isdigit

Podobne pytania

0 głosów
2 odpowiedzi 148 wizyt
pytanie zadane 11 listopada 2018 w C i C++ przez jankowa1ski Gaduła (3,560 p.)
0 głosów
2 odpowiedzi 565 wizyt
pytanie zadane 7 maja 2019 w PHP przez Luna Cognita Dyskutant (8,130 p.)
0 głosów
1 odpowiedź 689 wizyt
pytanie zadane 15 maja 2018 w C i C++ przez qlucha Obywatel (1,790 p.)

92,576 zapytań

141,426 odpowiedzi

319,651 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...