[C++] Sprawdzanie typu pobieranych danych 11096 20

O temacie

Autor MajkeI

Zaczęty 23.11.2014 roku

Wyświetleń 11096

Odpowiedzi 20

MajkeI

MajkeI

Użytkownicy
Front End Developer
posty698
Propsy169
Profesjabrak
  • Użytkownicy
  • Front End Developer
No więc mam taki kod
Spoiler
#include <iostream>

int main()
{
    int nr = 0;
    while (nr != 13) {

        std::cout << "Podaj numer od 1 do 12, lub 13" << std::endl;
        cin >> nr;

        switch(nr)
        {
            case 1:{ std::cout << "styczen" << std::endl; break;}
            case 2:{ std::cout << "luty" << std::endl; break; }
            case 3:{ std::cout << "marzec" << std::endl; break; }
            case 4:{ std::cout << "kwiecien" << std::endl; break; }
            case 5:{ std::cout << "maj" << std::endl; break; }
            case 6:{ std::cout << "czerwiec" << std::endl; break; }
            case 7:{ std::cout << "lipiec" << std::endl; break; }
            case 8:{ std::cout << "sierpien" << std::endl; break; }
            case 9:{ std::cout << "wrzesien" << std::endl; break; }
            case 10:{ std::cout << "pazdziernik" << std::endl; break; }
            case 11:{ std::cout << "listopad" << std::endl; break; }
            case 12:{ std::cout << "grudzien" << std::endl; break; }
            case 13:{ std::cout << "przerwano petle" << std::endl; break;}
            default:{ std::cout << "Blad" << std::endl; }
        }
    }
    return 0;
}

W tym przypadku zależy mi na pobraniu liczby całkowitej, czyli inta. Jeśli jednak podam jakiś znak (co może się zdarzyć użytkownikowi) program wariuje. Chciałbym sprawdzić jakiego typu jest nr, zaraz po wczytaniu, i jeśli nie jest intem równać mu 0. Pseudo-kod:
Spoiler
...
        cin >> nr;

        if (nr nie jest intem)
        {
            nr = 0;
        }
        switch(nr)
        {
...

Dobrze myślę? I jaki dać warunek? Próbowałem już if (typeid(nr) != typeid(int)) i dalej nie działało
 


MajkeI

MajkeI

Użytkownicy
Front End Developer
posty698
Propsy169
Profesjabrak
  • Użytkownicy
  • Front End Developer
Jestem raczej początkujący w c++, zrobiłem tak:
Spoiler
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
int main()
{
    int nr = 0;
    char buffer[256];
    while (nr != 13) {
        std::cout << "Podaj numer od 1 do 12, lub 13" << std::endl;
        fgets (buffer, 256, stdin);
        nr = atoi(buffer);
        switch(nr)
        {
            case 1:{ std::cout << "styczen" << std::endl; break;}
            case 2:{ std::cout << "luty" << std::endl; break; }
            case 3:{ std::cout << "marzec" << std::endl; break; }
            case 4:{ std::cout << "kwiecien" << std::endl; break; }
            case 5:{ std::cout << "maj" << std::endl; break; }
            case 6:{ std::cout << "czerwiec" << std::endl; break; }
            case 7:{ std::cout << "lipiec" << std::endl; break; }
            case 8:{ std::cout << "sierpien" << std::endl; break; }
            case 9:{ std::cout << "wrzesien" << std::endl; break; }
            case 10:{ std::cout << "pazdziernik" << std::endl; break; }
            case 11:{ std::cout << "listopad" << std::endl; break; }
            case 12:{ std::cout << "grudzien" << std::endl; break; }
            case 13:{ std::cout << "przerwano petle" << std::endl; break;}
            default:{ std::cout << "Blad" << std::endl; }
        }
    }
    return 0;
}

I działa. Ale jak to działa? Buffer to jest maksymalny zakres znaków jaki można pobrać? Funkcja fgets jest czymś w rodzaju cin?
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Po co używasz fgets jak używasz C++?
std::cin << buffer;
nr = atoi(buffer);

MajkeI

MajkeI

Użytkownicy
Front End Developer
posty698
Propsy169
Profesjabrak
  • Użytkownicy
  • Front End Developer
Tak jak piszesz wywala błedy :S
error: no match for 'operator<<' in 'std::cin << buffer'
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
W drugą stronę. :P
std::cin >> buffer;

MajkeI

MajkeI

Użytkownicy
Front End Developer
posty698
Propsy169
Profesjabrak
  • Użytkownicy
  • Front End Developer
Ah, no tak nie wpadłem na to o_0

no to teraz: error: stray '\357' in program
:/
EDIT: Fałszywy alarm - działa, dzięki :)
 

chicken

chicken

RaveN Studio
posty1230
Propsy559
ProfesjaNierób
  • RaveN Studio
Atoi konwertuje ciąg znaków na liczbę całkowitą.
Wg. nazwy tematu można wywnioskować, że chcesz sprawdzić typ, np.
typeid(myVar).name()
Teraz skonstruowanie instrukcji warunkowej nie powinno być trudne.

MajkeI

MajkeI

Użytkownicy
Front End Developer
posty698
Propsy169
Profesjabrak
  • Użytkownicy
  • Front End Developer
no więc zrobiłem tak
Spoiler
#include <iostream>
#include <typeinfo>
#include <stdio.h>
int main()
{
    int nr = 0;
    while (nr != 13) {
        printf("Podaj numer od 1 do 12, lub 13 \n");
        std::cin >> nr;
        if(typeid(nr).name() != "int")
        {
            if (nr <= 13 && nr >= 1)
            {
                switch(nr)
                {
                    case 1:{ printf("styczen \n"); break;}
                    case 2:{ printf("luty \n"); break; }
                    case 3:{ printf("marzec \n"); break; }
                    case 4:{ printf("kwiecien \n"); break; }
                    case 5:{ printf("maj \n"); break; }
                    case 6:{ printf("czerwiec \n"); break; }
                    case 7:{ printf("lipiec \n"); break; }
                    case 8:{ printf("sierpien \n"); break; }
                    case 9:{ printf("wrzesien \n"); break; }
                    case 10:{ printf("pazdziernik \n"); break; }
                    case 11:{ printf("listopad \n"); break; }
                    case 12:{ printf("grudzien \n"); break; }
                    case 13:{ printf("przerwano petle \n"); break;}
                }
            }
            else
            {
                printf("Wartosc spoza zakresu");
            }
        }
        else
        {
             printf("Blad");
        }
    }
    return 0;
}

Teraz jak wpiszę coś innego niż wartość liczbową, to powinno wyświetlić "Blad", a tutaj pokazuje mi to cały czas (zapętla) :S
Czemu tak jest?
 

chicken

chicken

RaveN Studio
posty1230
Propsy559
ProfesjaNierób
  • RaveN Studio
Spróbuj tak:
if (!strcmp(typeid(nr).name(), typeid(int).name()))

MajkeI

MajkeI

Użytkownicy
Front End Developer
posty698
Propsy169
Profesjabrak
  • Użytkownicy
  • Front End Developer
 

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Najlepiej debuguj kod. Poza tym powinieneś sprawdzać, czy zwracany typ to int, a nie sprawdzać, czy jest różny od inta.

chicken

chicken

RaveN Studio
posty1230
Propsy559
ProfesjaNierób
  • RaveN Studio
Najlepiej debuguj kod. Poza tym powinieneś sprawdzać, czy zwracany typ to int, a nie sprawdzać, czy jest różny od inta.
StrCmp - porównuje dwa stringi, zwraca 0, gdy są takie same.
Porównywane są dwie nazwy, nazwa typu wprowadzonych danych do strumienia wejściowego i nazwa typu int.

MajkeI

MajkeI

Użytkownicy
Front End Developer
posty698
Propsy169
Profesjabrak
  • Użytkownicy
  • Front End Developer
Najlepiej debuguj kod. Poza tym powinieneś sprawdzać, czy zwracany typ to int, a nie sprawdzać, czy jest różny od inta.
Cały czas debuguję, a co do kolejności sprawdzania, to nie ma znaczenia, próbowałem w obie strony.
Wiem, że switch jest bardzo mało używany i głównie korzysta się z instrukcji if, else - ale zaciekawiło mnie dlaczego się tak dzieje, choć nie powinno
 

inż. Avallach

inż. Avallach

Administrator
posty7661
Propsy5239
NagrodyV
ProfesjaProgramista
  • Administrator
OMG, czy ktokolwiek czyta jakie bzdury on tam napisał?
Cytuj
int nr = 0;
...
if(typeid(nr).name() != "int")
Skoro zadeklarowałeś to jako inta, to to zawsze będzie int, nie ważne co tam wstawisz (protip: nie wstawisz tam nic innego niż int lub coś konwertowalnego na inta). Poza tym nazwy "skompilowanych" typów nie są takie same jak te które wpisujesz. Zależą od kompilatora. Dla gcc będzie to po prostu "i". W ogóle to typeid nie używa się w ten sposób. W ogóle nie powinno się używać poza raczej wyjątkowymi sytuacjami, zwykle jest to oznaka tego że nie potrafisz używać polimorfizmu.

MajkeI

MajkeI

Użytkownicy
Front End Developer
posty698
Propsy169
Profesjabrak
  • Użytkownicy
  • Front End Developer
Skoro tak uważasz, to pewnie masz rację. Jest w c++ "var"? Wiem, że w c# jest i mogę go użyć. a tutaj?
 


MajkeI

MajkeI

Użytkownicy
Front End Developer
posty698
Propsy169
Profesjabrak
  • Użytkownicy
  • Front End Developer
auto nr; Czyżbym robił kolejny głupi błąd? Wywala coś debugger, ale zniknęło mi okno z błędami a w tym durnym API od CodeBlocksa nie idzie się połapać gdzie to włączyć
 

inż. Avallach

inż. Avallach

Administrator
posty7661
Propsy5239
NagrodyV
ProfesjaProgramista
  • Administrator
CodeBlocks :facepalm:
Czym kompilujesz? Jesteś pewien że twój kompilator obsługuje i ma włączony standard C++11?
Jeśli korzystasz z Windowsa, używaj Visual Studio. Jest darmowe także do użytku komercyjnego. Jeśli nie (lub brzydzisz się produktami MS (ten akurat jest bardzo dobry)) to CLiona od JetBrains. Na razie pre-alpha, ale i tak o niebo lepszy m.in. od Eclipse CDT (i zapewne od tego twojego odpowiednika glinanej tabliczki).

Adanos

Adanos

Administrator
Szara eminencja
posty5204
Propsy3870
ProfesjaProgramista
  • Administrator
  • Szara eminencja
Nie używasz najnowszego C++, albo podaj treść błędu. Moja rada: olej to sobie i zrób to co chcesz za pomocą atoi.


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry