Mikäs on kätevin konsti estää kirjainten syöttäminen kun kysytään lukua?
#include <iostream>
int main()
{
int luku = 0;
while (luku < 10)
{
std::cout << "Anna luku ";
std::cin >> luku;
}
return 0;
}Tulee ikuinen silmukka kun laittaa kirjaimen...
tarkistamalla ylipäätään onko kyseessä luku. tuo ei toimi muutenkaan, koska otat konsolisyötteestä merkkijonon muuttujaan joka on alustettu kokonaisluvuksi. konvertoi syöte ensi kokonaisluvuksi luku -muuttujaan, jos tämä epäonnistuu, tulosta validointivirhe ja pyydä luku uudestaan. jos muunto onnistuu, jatka.
Jaa että näinkö?
#include <iostream>
#include <cstdlib>
#include <cctype>
int main()
{
int luku = 0;
char merkki[5];
while (luku < 10)
{
std::cout << "Anna luku ";
std::cin >> merkki;
if (isalpha(merkki[0]))
std::cout << "Anna luku!\a\n";
luku = atoi(merkki);
}
return 0;
}Kun yritetään lukea tekstiä lukumuuttujaan, virta (cin) menee virhetilaan ja mikään lukeminen ei enää onnistu ennen virheen käsittelyä.
Pitää tarkastaa, onnistuiko lukeminen, ja tarvittaessa ohittaa viallinen rivi.
#include <iostream>
#include <limits>
int main() {
int luku = 0;
while (luku < 10) {
while (true) {
std::cout << "Anna luku: ";
// Jos ei tule virhettä, lopetetaan silmukka.
if (std::cin >> luku) {
break;
}
// Poistetaan virhemerkintä.
std::cin.clear();
// Ohitetaan rivi.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Ilmoitetaan virheestä ja toistetaan silmukkaa.
std::cout << "Syöte ei kelpaa!\n";
}
// Luku on luettu, tarkastetaan se.
if (luku < 10) {
std::cout << "Luku on liian pieni!" << std::endl;
}
}
}Jos tekstin alussa on luku ja sitten muita merkkejä, luvun lukeminen onnistuu ja merkit jäävät seuraavalle lukukerralle.
Toinen vaihtoehto on lukea rivi tekstinä ja koettaa muuttaa luvuksi.
#include <iostream>
#include <string>
#include <stdexcept>
int main() {
int luku = 0;
while (luku < 10) {
while (true) {
std::string teksti;
std::cout << "Anna luku: ";
// Luetaan rivi.
std::getline(std::cin, teksti);
// Yritetään muuttaa luvuksi, käsitellään virheet.
try {
luku = std::stoi(teksti);
break;
} catch (std::invalid_argument& e) {
std::cout << "Syöttämäsi teksti \"" << teksti << "\" ei ole luku." << std::endl;
} catch (std::out_of_range& e) {
std::cout << "Syöttämäsi luku " << teksti << " on liian suuri." << std::endl;
}
}
// Luku on luettu, tarkastetaan se.
if (luku < 10) {
std::cout << "Luku on liian pieni!" << std::endl;
}
}
}Tämä toimii hyvin, mutta nyt myös "7 kääpiötä" muuttuu luvuksi 7. Tähän voi tarvittaessa lisätä tarkastuksen, onko tekstissä muuta kuin numeroita.
if (teksti.find_first_not_of("0123456789") != std::string::npos) {
// tekstissä on muuta kuin numeroita.
}Koodia voisi kehittää vielä niin, että syötteen lopettaminen (Linuxissa Ctrl+D, Windowsissa Ctrl+Z) myös käsiteltäisiin ilman ohjelman jumiutumista.
Aihe on jo aika vanha, joten et voi enää vastata siihen.