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

Zabezpieczenie Int"a przed String"iem

Object Storage Arubacloud
+1 głos
896 wizyt
pytanie zadane 27 grudnia 2016 w C i C++ przez breeg Początkujący (390 p.)
#include <iostream>
#include <cstdlib>
#include <windows.h>
#include <math.h>
#include <fstream>
#include <time.h>
#include <conio.h>
using namespace std;

float weight,height,score,score1;

float bmi_score(float score);


int main()
{
    cout << "Program do obliczania Bmi!" << endl;
    cout << "--------------------------" << endl;

    int choice;
    string choice2="1";
    while(choice2!="2")         // petla ktora wraca do poczatku
    {
    cout<<"Co chcesz zrobic?!"<<endl;
    cout<<"1)Sprawdz swoje BMI!"<<endl;       // Pocz¹tek programu
    cout<<"2)Wyjdz z programu!"<<endl;
    cout<<"Wybierz: ";
    cin>>choice;
    system("cls");


    switch(choice)                            //wybór rozpaczecia
    {

    case 1:



    cout << "Podaj swoja wage(kg)! ";
    cin>>weight;                              //zmienne do BMI
    cout << "Podaj swoj wzrost(cm)! ";
    cin>>height;

    if (weight<=0 || height <=0)
    {
        cout<<"Waga tak jak i wzrost musza byc wieksze od zera..."<<endl;      //Zabezpiecza przed podaniem liczby "0" 
    }

    else
    {
    cout<<"Twoje BMI!: ";
                                  //wynik BMI
    score=bmi_score(score);
    cout<<score<<endl;

    if (score<16)
    {
    cout<<"Wyglodzenie!"<<endl;
    }
    else if (score>=16 && score <=17)
    {
    cout<<"Wychudzenie!"<<endl;
    }                                                                                ////////warunki BMI

    else if (score>17 && score <18.5)
    {
    cout<<"Niedowaga!"<<endl;
    }

    else if (score>=18.5 && score <25)
    {
    cout<<"Waga prawidlowa!"<<endl;
    }

    else if (score>=25 && score <30)
    {
    cout<<"Nadwaga!"<<endl;
    }

    else if (score>=30 && score <35)
    {
    cout<<"I stopien otylosci!"<<endl;
    }

    else if (score>35)
    {
    cout<<"II stopien otylosci!"<<endl;
    }
    }
    cout<<endl<<"Co chcesz teraz zrobic ?"<<endl;
    cout<<"1)Licz jeszcze raz!"<<endl;
    cout<<"2)Wyjdz z programu!"<<endl;
    cout<<"Wybierz: ";
                   //wraca lub konczy program

    cin>>choice2;
    system("cls");

    if (choice2=="2")
    {
     system("cls");
     cout<<"Do zobaczenia !..."<<endl;
     Sleep(3000);                         //wyjscie z programu
     exit(0);
    }
    else if (choice2!="1" && choice2!="2")
    {
        cout<<"Wprowadziles zly znak! Program za chwile wroci do poczatku..."<<endl;
        Sleep(3000);
        system("cls");
    }


    break;


    case 2:

     system("cls");
     cout<<"Do zobaczenia !..."<<endl;
     Sleep(3000);                         //wyjscie z programu
     exit(0);

    break;



    }

    }

    return 0;
}


float bmi_score(float score)
{
    score=weight/pow(height,2)*10000 ;                //liczy bmi

    time_t czas;
    time( & czas );                           //podaje dokładny czas
    char * data = ctime( & czas );



    fstream plik;
    plik.open("bmi.txt",ios::out | ios::app);                              // zapisuje bmi i date do pliku
    plik<<"BMI: "<<score<<" /Data-";
    plik<<data;
    plik.close();
    return score;
};

Mam problem tego typu ze nie wiem jak zabezpieczyć program przed podaniem znaków zamiast cyfr ;d uprzedzam ze jest to jeden z moich pierwszych programów wiec kod moze byc słabo napisany :d prosze tez o jakies wskazówki co moge w nim poprawić :) 

komentarz 27 grudnia 2016 przez breeg Początkujący (390 p.)
 if (weight<=0 || height <=0)
    {
        cout<<"Waga tak jak i wzrost musza byc wieksze od zera..."<<endl;      //Zabezpiecza przed podaniem liczby "0" 
    }
 

w kodzie jest taki if :) i dołączam do tego pytania czy da sie dopisać jeszcze jakiś warunek przed podanie stringa do tego ifa ? :) 

1 odpowiedź

+1 głos
odpowiedź 27 grudnia 2016 przez plkpiotr Stary wyjadacz (12,420 p.)
edycja 27 grudnia 2016 przez plkpiotr
 
Najlepsza

Może po prostu pobierać dane, dopóki strumień okaże się poprawny:

int zmienna; // lub inny wbudowany typ liczbowy
cin >> zmienna;
while (!cin.good()) { // warunek niepoprawnosci strumienia
    cin.clear();
    cin.ignore(liczbaZnakow, '\n'); // bardziej profesjonalnie: std::cin.ignore(std::numeric_limits < std::streamsize >::max(), '\n' );
    cin >> zmienna;
}

Co można jeszcze zrobić? Sformatować nieco kod, aby był bardziej czytelny dla innych poprzez dodanie wcięć i usunięcie pustych linii. Jeśli działasz pod Code::Blocks to PPM -> format use AStyle. Samo usuwanie linii odbywa się przez ctrl+l. Oszczędziliśmy tym samym około pięćdziesiąt linijek...

#include <iostream>
#include <cstdlib>
#include <windows.h>
#include <math.h>
#include <fstream>
#include <time.h>
#include <conio.h>
using namespace std;

float weight, height, score, score1;
float bmi_score(float score);

int main() {
    cout << "Program do obliczania Bmi!" << endl;
    cout << "--------------------------" << endl;
    int choice;
    string choice2 = "1";
    while (choice2 != "2") {    // petla ktora wraca do poczatku
        cout << "Co chcesz zrobic?!" << endl;
        cout << "1)Sprawdz swoje BMI!" << endl;   // Pocz¹tek programu
        cout << "2)Wyjdz z programu!" << endl;
        cout << "Wybierz: ";
        cin >> choice;
        system("cls");
        switch (choice) {                         //wybór rozpaczecia
        case 1:
            cout << "Podaj swoja wage(kg)! ";
            cin >> weight;                            //zmienne do BMI
            cout << "Podaj swoj wzrost(cm)! ";
            cin >> height;
            if (weight <= 0 || height <= 0) {
                cout << "Waga tak jak i wzrost musza byc wieksze od zera..." << endl;  //Zabezpiecza przed podaniem liczby "0"
            } else {
                cout << "Twoje BMI!: ";
                //wynik BMI
                score = bmi_score(score);
                cout << score << endl;
                if (score < 16) {
                    cout << "Wyglodzenie!" << endl;
                } else if (score >= 16 && score <= 17) {
                    cout << "Wychudzenie!" << endl;
                }                                                                                ////////warunki BMI
                else if (score > 17 && score < 18.5) {
                    cout << "Niedowaga!" << endl;
                } else if (score >= 18.5 && score < 25) {
                    cout << "Waga prawidlowa!" << endl;
                } else if (score >= 25 && score < 30) {
                    cout << "Nadwaga!" << endl;
                } else if (score >= 30 && score < 35) {
                    cout << "I stopien otylosci!" << endl;
                } else if (score > 35) {
                    cout << "II stopien otylosci!" << endl;
                }
            }
            cout << endl << "Co chcesz teraz zrobic ?" << endl;
            cout << "1)Licz jeszcze raz!" << endl;
            cout << "2)Wyjdz z programu!" << endl;
            cout << "Wybierz: ";
            //wraca lub konczy program
            cin >> choice2;
            system("cls");
            if (choice2 == "2") {
                system("cls");
                cout << "Do zobaczenia !..." << endl;
                Sleep(3000);                         //wyjscie z programu
                exit(0);
            } else if (choice2 != "1" && choice2 != "2") {
                cout << "Wprowadziles zly znak! Program za chwile wroci do poczatku..." << endl;
                Sleep(3000);
                system("cls");
            }
            break;
        case 2:
            system("cls");
            cout << "Do zobaczenia !..." << endl;
            Sleep(3000);                         //wyjscie z programu
            exit(0);
            break;
        }
    }
    return 0;
}

float bmi_score(float score) {
    score = weight / pow(height, 2) * 10000 ;         //liczy bmi
    time_t czas;
    time( & czas );                           //podaje dokładny czas
    char * data = ctime( & czas );
    fstream plik;
    plik.open("bmi.txt", ios::out | ios::app);                             // zapisuje bmi i date do pliku
    plik << "BMI: " << score << " /Data-";
    plik << data;
    plik.close();
    return score;
}

Dodatkowo można pozbyć się nawiasów klamrowych w wyrażeniach if lub if else gdzie mamy do czynienia z jedną instrukcją, ponieważ gdy mamy jedną instrukcję w if'ach, czy w pętli to klamerki nie są potrzebne - ponownie skrócimy nasz kod : )

Tak na pierwszy rzut oka można byłoby pomyśleć o multiplatformowym czyszczeniu konsoli, aby nie ograniczać się wyłącznie do Windowsa... Może coś na wzór takiego rozwiązania, które można umieścić w pliku źródłowym:

#ifdef _WIN32 || _WIN64
#include <windows.h>
void clearScreen() {
    system("cls");
}
#else
#include <cstdio>
void clearScreen() {
    printf("\033[2J"); // Screen
    printf("\033[0;0f"); // Cursor
}

#endif

Wtedy aby wyczyścić konsolę wywołujemy funkcję clearScreen() - może ona nazywać się oczywiście inaczej.

komentarz 27 grudnia 2016 przez breeg Początkujący (390 p.)
cin.ignore(liczbaZnakow, '\n'); 

dzięki wielkie :) pomogłeś bardzo :) jeszcze jakbyś mógł tak dobrze wytłumaczyć o co chodzi w powyższej funkcji :) byłbym wdzięczny :)

komentarz 27 grudnia 2016 przez plkpiotr Stary wyjadacz (12,420 p.)

Nie ma sprawy ; ) Cieszę się, że mogłem pomóc : )

Wobec tego rozważmy [1] i [2] linijkę jeszcze raz:

cin.clear();
cin.ignore(1000, '\n');

Jak widać dokonujemy operacji na strumieniu wejściowym cin. To co jest po kropce to metody (funkcje wykonywane na rzecz strumienia). Język C++ w zależności od jego stanu ustawia flagi (pojedyncze bity) na stan 0 (false) lub 1 (true). Te bity to:

  • goodbit - true gdy wszystko ze strumieniem w porządku
  • badbit - true gdy np. próbujemy czytać z pliku, który został usunięty
  • failbit - true gdy podamy niewłaściwy format danych (Twój przypadek)
  • eofbit - true gdy chcemy przeczytać dane znajdujące się za znakiem końca pliku

U nas po wpisaniu liter zamiast liczb failbit został ustawiony na true, tym samym goodbit na false. Do ponownego, poprawnego działania w strumieniu musimy wyczyścić flagi błędów metodą clear() (bez argumentów), tym samym failbit zostanie ustawiony na false, a goodbit wraca do true. [1]

No dobrze flaga błędów nie informuje już nas o błędzie, ale nadal na strumieniu nie możemy działać, zatem pomińmy te znaki które były w strumieniu do znaku nowego wiersza (entera) - wszystkie te, które spowodowały błąd, dlatego ustawia tam się dużą liczbę np. 1000 znaków, aby były wyczyszczone. [2]
Od teraz możemy działać na strumieniu (np. wczytywać z klawiatury).

Bibliografia ; )
clear() - en.cppreference.com oraz flagi - tabela na końcu artykułu - en.cppreference.com

Podobne pytania

0 głosów
3 odpowiedzi 718 wizyt
pytanie zadane 23 listopada 2016 w C i C++ przez String Gaduła (4,520 p.)
0 głosów
1 odpowiedź 195 wizyt
0 głosów
1 odpowiedź 812 wizyt
pytanie zadane 16 listopada 2018 w C i C++ przez robertwe Gaduła (4,620 p.)

92,551 zapytań

141,393 odpowiedzi

319,524 komentarzy

61,936 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!

...