Problem z programem c++ - ograniczenie zakresu wpisywanych liczb

0

Dzień dobry, próbuję napisać program, ale napotkałem pewien problem. Użytkownik ma wpisać 20 liczb w zakresie 1-100, następnie komputer losuje 10 liczb(również z zakresu 1-100). Potem program wyświetla posortowane rosnąco liczby i informacje ile liczb trafił użytkownik. Problem występuje w podanym zakresie - nie wiem co zrobić, aby nie można było wpisać liczb spoza zakresu 1-100. Z góry dziękuję za pomoc.

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int t[20],i,tym,a=0,wyl[10],b;
bool zmiana=true;
int main()
{
    cout<<"Podaj 20 liczb do losowania w zakresie 1-100!"<<endl;
    do
    {

          if(a<20)
        {
            cin>>t[a];
            a++;
        }
        else
          break;
    }
    while(t[a]<100||t[a]>1);

      srand(time(NULL));
    for(i=0;i<=9;i++)
    {
        wyl[i]=rand()%100+1;
    }
    while(zmiana)
    {
        zmiana=false;
        for(i=0;i<=8;i++)
        {
            if(wyl[i]>wyl[i+1])
            {
                tym=wyl[i];
                wyl[i]=wyl[i+1];
                wyl[i+1]=tym;
                zmiana=true;
            }
        }
    }
    cout<<"Oto liczby wylosowane za pomoca maszyny losujacej: "<<endl;
       for(i=0;i<=9;i++)
    {
        cout<<wyl[i]<<" ";
    }

    int trafione=0;
    for(int i=0;i<10;++i)
        for(int j=0;j<20;++j)
        if(t[j]==wyl[i])
        {
            ++trafione;
            break;
        }
        cout<<"Trafiles: "<<trafione;

    return 0;

}
1

Najpierw ustalasz zmienna globalną, (bardzo źle) a = 0, potem sprawdzasz, czy a < 20 - to będzie prawdą zawsze, i na koniec czytasz z klawiatury, a - czyli użytkownik może podać dowolną liczbę.
EDYCJA: Trochę się minąłem z prawdą, znaczy ten warunek jest bez sensu, ale problem jest też inny; t[a]<100||t[a]>1) to będzie prawdą gdy co najmniejjeden z warunków jest spełniony, a nie obydwa, jak powinno być.

0

Dzięki zapisowi a<20 sprawiam, że użytkownik nie może podać więcej niż 20 liczb. Nie do końca wiem natomiast jak sprawić, aby był brak możliwości wpisywania liczb spoza zakresu.

0

Zmień warunek while(t[a]<100||t[a]>1); na while(t[a]<=100&&t[a]>=1);, bo liczba ma być i mniejsza lub równa 100 i większa lub równa 1. U Ciebie jest większa od 1 LUB mniejsza od 100, więc to zawsze będzie spełnione niezależnie od podanej liczby

0

Najprostszy sposób to zamknąć podawanie przez użytkownika liczb w pętli trwającej do czasu, aż nie poda wszystkich poprawnie.
Za każdym razem, gdy użytkownik poda złą liczbę rzucaj błąd i zapętlaj do podawania liczby.
Coś podobnego masz już zrobione, ale problem w tym, że Twoja pętla przerwie się przy pierwszej błędnie podanej liczbie.
Najprościej byłoby zrobić pętlę od a < 20 i zagnieżdżoną pętlę od zakresu 1 < t[a] < 100.

0

Problem widzę tu:

    do
    {

          if(a<20)
        {
            cin>>t[a];
            a++;
        }
        else
          break;
    }
    while(t[a]<100||t[a]>1);

Po kroku N pętli warunek w while się psuje, bo sprawdza na nieistniejącym elemencie:

  • w pętli inkrementujesz do a=N+1
  • w warunku pętli sprawdzisz nieistniejący element t[N+1]

Jak dla mnie to zacząłbym od tego, że wszystko jest wywrócone na nice - w trzewiach pętli pilnujesz liczby kroków, w warunku pętli sprawdzasz czy została wczytana liczba taka, jak trzeba.

Prościej byłoby napisać to samo tak:

for(int a=0; a<20; a++) {
  // wczytaj t[a]
  // zrób coś jeśli t[a] nie mieści się w zakresie 1...100
}

Albo nawet tak:

for(int a=0; a<20;) {
  // wczytaj x
 if(....) { // x mieści się w zakresie 
    t[a] = x;
    a++;
  }
}
0

Po zmianie "||" na "&&" program przyjmuje tylko 2 liczby, a następnie się przerywa, chociaż nie można wpisać już liczby spoza zakresu

do
    {

          if(a<20)
        {
            cin>>t[a<100];
            a++;
        }
        else
          break;
    }
    while(t[a]<=100&&t[a]>=1);

0

Najpierw inkrementujesz licznik, potem sprawdzasz warunek - zamiast zrobić odwrotnie. Nie zapisałeś jeszcze nic do sprawdzanego elementu tablicy (może tam być cokolwiek - zera, losowe śmieci które były w pamięci przed alokacją).

0

@Misterekowsky:, @superdurszlak: A jak się nie mieści, to znowu musi wczytać, a jak wtedy znów poda błędnie? Lepiej zrobić to w pętli while przerywanej, gdy długość poprawnie wczytanej tablicy będzie równa 20.

0

Kurcze, pogubiłem się trochę. Czy mógłby ktoś mi powiedzieć co musze napisać, aby program działał poprawnie ? Z góry dzięki.

0

Program nie działa między innymi dlatego, że inkrementujesz swój licznik (a++) po dodaniu elementu t[a] do tablicy, ale zanim sprawdzisz (w warunku pętli), czy t[a] spełnia warunek.

W momencie, gdy już zrobiłeś inkrementację i sprawdzasz t[a] - sprawdzasz kolejny element, który nie istnieje i może tam być cokolwiek (w najlepszym wypadku zero, w najgorszym przypadkowe rzeczy).

Poza tym tak, jak to teraz napisałeś - pętla zakończy się, gdy użytkownik poda nieprawidłową liczbę. Jak chcesz, żeby tak było, to spoko - ale jak nie, to zamiast przerywać gdy coś się nie zgadza wczytywać do skutku.

0

Chciałbym, żeby po podaniu liczby spoza zakresu pętla wczytywała się do skutku, tylko nie wiem co konkretnie muszę zmienić, aby program działał poprawnie.

1

Tak jak napisałem, musisz użyć pętli while:

    int a = 0;
    int arr[20];
    int size = 0;
    std::cout << "Podaj 20 liczb z zakresu 1 - 100\n";
    while (size < 20) {
        std::cin >> a;
        if (a < 101 && a > 0) {
            arr[size] = a;
            ++size;
        }
        else {
            std::cout << "Zakres 1 - 100! Podaj jeszce raz!\n";
            continue;
        }
    }
0
Misterekowsky napisał(a):

Chciałbym, żeby po podaniu liczby spoza zakresu pętla wczytywała się do skutku, tylko nie wiem co konkretnie muszę zmienić, aby program działał poprawnie.

No to to jest ten wariant mniej więcej

for(int a=0; a<20;) {
  // wczytaj x
 if(....) { // x mieści się w zakresie
    t[a] = x;
    a++;
  }
}

Pętla działa tak długo, jak nie ma prawidłowych 20 elementów. Licznik zwiększasz, gdy wczytana wartość jest prawidłowa (i wtedy też dopisujesz do tablicy). Możesz to jakoś inaczej zapisać, ale idea pozostaje ta sama.

0

Dziękuję wszystkim za poświęcony czas. Problem rozwiązany sposobem @lion137.

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