Wykrycie wpisania poprawnej wartości

0

Witam, mam dwa pytania:

  1. Chciałem napisać fragment kodu, który wykrywa, czy wpisana wartość za pomocą cin to liczba, jeżeli nie, to program prosi o ponowne podanie liczby. Korzystając z ksiązki Praty o programowaniu w C++, wykorzystałem "trik" z wykryciem pobrania poprawnej wartości i zwrócenia wyniku przez cin i napisałem coś takiego:
#include <iostream> 
#include <string>
#include <cctype>

using namespace std;

int main()
{
    int liczba;

    cout<<"Prosze wpisac liczbe, a przejde dalej"<<endl;

    while( !(cin>>liczba) )
    {
        cout<<"Nie podales liczby! Sproboj ponownie"<<endl;
        cin.clear();
        while(cin.get() != '\n')
            continue;
    }

    cout<<"Koniec"<<endl;

    return 0;
}

Program działa, ale jeżeli wpiszę np "12qwerty" to pobiera liczby do pierwszego znaku. Ktoś wie, jak wyeliminować ten błąd? Pewnie można wstawić na początku pętli jakiegoś if, tylko jakiego?

  1. Podobny program co poprzedni, tylko tym razem zamiast liczby żąda znaku:
#include <iostream> //"Zrobic cw z rozdzialu 8: 2, 3, 5, 6"
#include <string>
#include <cctype>

using namespace std;

int main()
{
    char znak;

    cout<<"Prosze wpisac znak, a przejde dalej"<<endl;

    while( !(cin>>znak) )
    {
        cout<<"Nie podales znaku! Sproboj ponownie"<<endl;
        cin.clear();
        while(cin.get() != '\n')
            continue;
    }

    cout<<"Wpisales znak "<<znak<<endl;

    return 0;
}

Jak wiemy wartością char może być np literka A, ale także cyfra 2. Jak zrobić, aby w programie nr 2 program interpretował zmienną znak jako tylko znaki? Czy nie da się tego zrobić wykorzystując ten trik z obiektem cin?

1

W cctype są, na przykład, funkcje isdigitoraz isalnum, Spróbuj z nimi.
http://www.cplusplus.com/reference/cctype/

0

Interesuje cię:

1

@kario97: To o czym piszesz, to nie są błędy.:)

kario97 napisał(a):
  1. Program działa, ale jeżeli wpiszę np "12qwerty" to pobiera liczby do pierwszego znaku. Ktoś wie, jak wyeliminować ten błąd? Pewnie można wstawić na początku pętli jakiegoś if, tylko jakiego?

Można zrobić różne sztuczki, tak jak Koledzy pisali już, ale z punktu widzenia C++ i logiki jego wczytywania, to 12qwerty wczytuje się jako 12, bo da się sparsować jako liczbę, a potem zatrzymuje się na q. Co więcej, to się przydaje -- dzięki temu możesz sobie wczytać 12:34 (godzinę z minutami) tak:

int godzina, minuty;
char dwukropek;
cin >> godzina >> dwukropek >> minuty;

Żeby to załatwić po Twojemu, trzeba wczytywać całe słowo (najlepiej do stringa), a potem to słowo parsować (np. przez stringstream).

  1. Jak wiemy wartością char może być np literka A, ale także cyfra 2. Jak zrobić, aby w programie nr 2 program interpretował zmienną znak jako tylko znaki? Czy nie da się tego zrobić wykorzystując ten trik z obiektem cin?

A tu Twoich wątpliwości w ogóle nie rozumiem... Przecież 2 jest takim samym znakiem jak A czy jak + -- więc się wczytuje i już. W drugim przykładzie Twoja pętla się nigdy nie wykona, bo znak zawsze da się wczytać. Wyjątkiem są znaki białe, ale ich pętla nie obejmie bo są ignorowane (domyślnie), więc jest całkiem niepotrzebne (w Twojej postaci).

0
koszalek-opalek napisał(a):

[...] W drugim przykładzie Twoja pętla się nigdy nie wykona, bo znak zawsze da się wczytać. Wyjątkiem są znaki białe, ale ich pętla nie obejmie bo są ignorowane (domyślnie), więc jest całkiem niepotrzebne (w Twojej postaci).

A przepraszam -- może się chyba wykonać, gdy ktoś da znak końca pliku...

0
koszalek-opalek napisał(a):

@kario97: To o czym piszesz, to nie są błędy.:)

kario97 napisał(a):

A tu Twoich wątpliwości w ogóle nie rozumiem... Przecież 2 jest takim samym znakiem jak A czy jak + -- więc się wczytuje i już. W drugim przykładzie Twoja pętla się nigdy nie wykona, bo znak zawsze da się wczytać. Wyjątkiem są znaki białe, ale ich pętla nie obejmie bo są ignorowane (domyślnie), więc jest całkiem niepotrzebne (w Twojej postaci).

Znaczy chodziło mi o to, żeby program pobierał tylko literę, a w przypadku pobrania innego znaku, np cyfry, to pojawia się błąd i trzeba jeszcze raz podać znak. Jak to zrobić?

0
kario97 napisał(a):
koszalek-opalek napisał(a):

@kario97: To o czym piszesz, to nie są błędy.:)

kario97 napisał(a):

A tu Twoich wątpliwości w ogóle nie rozumiem... Przecież 2 jest takim samym znakiem jak A czy jak + -- więc się wczytuje i już. W drugim przykładzie Twoja pętla się nigdy nie wykona, bo znak zawsze da się wczytać. Wyjątkiem są znaki białe, ale ich pętla nie obejmie bo są ignorowane (domyślnie), więc jest całkiem niepotrzebne (w Twojej postaci).

Znaczy chodziło mi o to, żeby program pobierał tylko literę, a w przypadku pobrania innego znaku, np cyfry, to pojawia się błąd i trzeba jeszcze raz podać znak. Jak to zrobić?

@lion137 pisał -- rzuć okiem tutaj:
https://en.cppreference.com/w/cpp/string/byte/isalpha
Twój program mógłby wyglądać tak (nie sprawdziłem, mogą być błędy):

#include <iostream>
#include <cctype>

using namespace std;

int main()
{
    char znak;

    cout<<"Prosze wpisac znak, a przejde dalej"<<endl;
    cin >> znak;
    while( !isalpha(znak) )
    {
        cout<<"Nie podales LITERY! Sproboj ponownie"<<endl;
        cin >> znak;
    }

    cout<<"Wpisales LITERĘ "<<znak<<endl;
    return 0;
}
0

Wydaje mi się, że chodziło bardziej o coś takiego:

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

int is_number(std::string str){
	for (int i = 0; i <str.length(); i ++){
		if (! std::isdigit(str[i])) return 0;
	}
	return 1;
}

int main(){
	std::string inp = "";
	bool ctr = true;
	
	while (ctr){
		std::cout << "Enter a number: ";
		std::cin >> inp; // <- 42
		std::cout << "\n";
		if (! is_number(inp))
			continue; 
		else
			ctr = false;
	}
	std::cout << "the number is: " << std::stoi(inp) << "\n"; // -> 42
	return 0;
}

Metodami z cctype Możesz toworzyć inne funkcje (nie tylko is_number - sprawdza tylko czy wejście może być skonwersowane do dodatniej liczby całkowitej)

1 użytkowników online, w tym zalogowanych: 0, gości: 1