Quiz – nie czyta pierwszych dwóch odpowiedzi pierwszego pytania

0

Cześć,

Postanowiłem zrobić quiz jak w odcinku 7 Zelanta.
Wszystko rozumiem ale nie czyta mi pierwszych dwóch odpowiedzi pierwszego pytania. Dodatkowo jeśli odpowiem poprawnie program i tak traktuje to jako złą odpowiedz. Z góry dziekuje za krytyczne uwagi

#include <iostream>
#include <fstream>
#include<cstdlib>
#include<string>
#include<algorithm>
#include<cctype>
using namespace std;
string temat,nick;
 string linia;
string tresc[5];
string odpA[5],odpB[5],odpC[5],odpD[5],poprawna[5];
string odpowiedz;
int punkty=0;

int main()
{
    fstream plik;
 int nr_linii=1;

 int nr_pytania=0;

   plik.open("plik.txt",ios::in);
   //test na istnienie pliku
   if(plik.good()==false)
   {

       cout<<"plik nie istnieje"<<endl;
       exit(0);
   }

   while(getline(plik,linia))
   {

         switch(nr_linii)
         {
             case 1: temat=linia;break;
             case 2: nick=linia;break;
             case 3: tresc[nr_pytania]=linia; break;
             case 4: odpA[nr_pytania]=linia; break;
             case 5: odpB[nr_pytania]=linia; break;
             case 6: odpC[nr_pytania]=linia; break;
             case 7: odpD[nr_pytania]=linia; break;
             case 8: poprawna[nr_pytania]=linia; break;

         }
            if(nr_linii==8)
            {

                   nr_linii=2;

                 nr_pytania++;
            }
     nr_linii++;
   }

   plik.close();

   for(int i=0;i<=4;i++)
   {
       cout<<endl<<tresc[i]<<endl;
       cout<<"A. "<<odpA[i]<<endl;
       cout<<"B. "<<odpB[i]<<endl;
       cout<<"C. "<<odpC[i]<<endl;
       cout<<"D. "<<odpD[i]<<endl;

       cout<<odpA[0];

      cout<<"Twoja odpowiedz: "<<endl;
      cin>>odpowiedz;

      transform(odpowiedz.begin(),odpowiedz.end(),odpowiedz.begin(),::tolower);
      if(odpowiedz == poprawna[i])
      {
        cout<<"Dobrze, zdobywasz punkt "<<endl;
        punkty++;
      }
      else cout<<"Zla odpowiedz. Poprawna to "<<poprawna[i]<<endl;
   }

system("PAUSE");
    return 0;
}
3
Postanowiłem zrobić quiz jak w odcinku 7 Zelanta.

wypadaloby dac link czy cos albo tresc. Teraz mam szukac siodmego odcinku zelenta zeby dowiedziec sie o co chodzi?

Z góry dziekuje za krytyczne uwagi

wiec
1) nie uzywa sie zmiennych globalnych
2) zapomnij o tablicach i uzywaj std::vector
3) pozbadz sie magic numbers
4) podziel program na funkcje. Bo teraz masz wszystko w jednej funkcji co nie jest dobra praktyka
5) uzywales debugerra?

0

ponizej link do kursu

http://miroslawzelent.pl/kurs[...]ekstowe-zapis-odczyt-fstream/

Dzieki za porady.
Co moze byc wynikiem blednie dzialajacego programu?
Czemu nam zapomniec o tablicach na rzecz wektorow?
Zastanawia mnie czemu w tablicy odpA[] nie zapisuje zerowego elementu a juz kolejne zapisuje w tablicy poprawnie.
Macie jakis pomysl czemu nie dziala kod gdzie funkcja if sprawdzam poprawnosc odpowiedzi?

0

Sprawdzanie odpowiedzi nie działa Ci przez to:
transform(odpowiedz.begin(),odpowiedz.end(),odpowiedz.begin(),::tolower);
Zamieniasz dużą literę na małą, a w pliku odpowiedź poprawna jest dużą literą, po co ten zabieg?

cout<<odpA[0];
Ten cout wypisuje pierwszą odpowiedź z pierwszego pytania przed każdym zapytaniem o odpowiedź, więc to skasuj, bo to niepotrzebne.

 if(nr_linii==8)
   {
     nr_linii=2;
     nr_pytania++;
    }

Ta instrukcja wyżej powoduje naruszenie pamięci, ponieważ co w przypadku gdy nr_pytania wskakuje na wartość 5? Pętla działa dalej, a jedzie wtedy po niedozwolonym obszarze(wyszedł poza zakres).
Dlatego trzeba dodać jakieś sprawdzanie, aby w odpowiednim momencie wyskoczył z pętli, czyli np coś w tym stylu:

nr_pytania++
if(nr_pytania == 5)
    break;

Mi wypisuje te dwie pierwsze odpowiedzi pierwszego pytania, chociaż na początku faktycznie znikało. Sprawdź jeszcze raz po modyfikacjach.

Jeśli chodzi o uwagi to oprócz tego co napisał fasadin to jeszcze dodam od siebie:
1)Nie ucz się z kursu Zelenta, ponieważ uczy tam wielu złych nawyków, chociażby zmienne globalne
2)Nie deklaruj zmiennych w ten sposób: string odpA[5],odpB[5],odpC[5],odpD[5],poprawna[5]; kod staje się przez to nieczytelny
Deklaruj w osobnych liniach:

string odpA[5];
string odpB[5];

3)To samo z takimi zapisami: case 1: temat=linia;break; oraz else cout<<"Zla odpowiedz. Poprawna to "<<poprawna[i]<<endl;
Osobne linie:

case 1: 
    temat = linia; 
    break;
else
    cout<<"Zla odpowiedz. Poprawna to "<<poprawna[i]<<endl;

Przy bardziej skomplikowanych instrukcjach staje się to nieczytelne.

Czemu nam zapomniec o tablicach na rzecz wektorow?

Chociażby dlatego, że wektory mają większe możliwości i tablic statycznych nie ma sensu używać, przyzwyczajaj się do dobrych nawyków, dlatego korzystaj z wektorów.

W przypadku błędów korzystaj z debuggera, bo bardzo ułatwia ich wyszukiwanie.

0

super dziekuje.Sprawdze po poprawkach i dam znac.
Bardzo merytoryczna odpowiedz jeszcze raz dzieki i wesolych swiat.

0

I również wesołych. Tak jeszcze dodam, bo zapomniałem, że wyjście poza zakres pamięci ma niezdefiniowane zachowanie co może się objawić różnymi rzeczami. Wydaje mi się, że program nie wyświetlał dwóch pierwszych odpowiedzi z tego właśnie powodu, bo we wczytywaniu raczej jest wszystko w porządku, a ono nie zostało zmodyfikowane, oprócz naprawy wyjścia poza zakres.

Jeszcze odnośnie tego kawałka kodu:

if(nr_linii==8)
  {
     nr_linii=2;
     nr_pytania++;
  }
     nr_linii++;

To jest trochę mało czytelne, bo ustawiasz nr_linii na wartość 2, dlatego bo zaraz zostanie zwiększona o jeszcze jeden i będzie miała wartość 3, która jest w tym kodzie potrzebna do wczytywania pytań. Lepiej, żeby z kodu od razu było wiadomo, że ustawiasz na wartość 3, spróbuj np użyć else do warunku, żeby zrobić to w bardziej czytelny sposób.

0

Dziekuje .Jak tylko wroce od rodziny ze swiat to wyprobuje poprawiony kod.

0

Sprawdzilembi wszystko dziala.Faktycznie blad spowodowany byl brakiem warunku na nr_pytania.Po wpisaniu ograniczenia w petli program zaczal dzialac poprawnie.

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