Poprawny kod a niepełny odczyt danych programu

0

Cześć wszystkim!
Zacząłem naukę C++ i trafiłem na pierwsze schody. Robię ćwiczenie z filmiku:

Generalnie ćwiczę sobie tak, że następnego dnia zawsze robie sobie wszystko "z głowy" i wprowadzam swoje mini modyfikacje ale tutaj robiac wszystko tak samo krok w krok, nie mogę dojść o co chodzi.
Napisałem swój kod i program nie odczytuje mi treści odpowiedzi A. i B. (tylko i wyłącznie w pierwszym pytaniu) oraz podaje, że ostatnie pytanie to odpowiedź zła a poprawna jest odpowiedź "a" pomimo tego, że to właśnie poprawna odpowiedź.
Ostatecznie pobrałem pliki od autora zadania, sprawdzałem kod linijka po linijce a w końcu przekleiłem cały kod autora i zmieniłem jedynie nazwę pliku, który ma być odczytany na własny plik i problem dalej jest ten sam.. (Oczywiscie program autora z tym samym kodem tylko jego plikiem odpowiedzi działa poprawnie na moim komputerze).
Pliki z odpowiedziami również sprawdzałem, mają tyle samo wierszy i wszystko IMO się zgadza.
Załączam screeny i będę wdzięczny za wytłumaczenie w czym problem bo jeśli nie w kodzie to może mam źle zainstalowany progam? Wcześniej od czasu do czasu miałem małe błędy na które udawało mi się znaleźć rozwiązanie a które np. nie występowały na filmikach z tego kanału.

PS. Ćwicząc zapis do pliku miałem w sumie podobny problem: miałem dwie odpowiedzi (pierwszą i trzecią) zawierające albo "tekstA tekstB" albo np. "24 marca" i w momencie jak poprawnie zapisywała się linijka "tekst A tekst B" to linijka "24 marca" zapisywała się "marca" i odwrotnie. Kombinując i szukając rozwiązań czasem program też poprawnie "zbierał" odpowiedzi aż do pytania o "24 marca", które wyświetlał ale pomijał możliwość jej wpisania i dalej poprawnie wyświetlał kolejne pytanie.
Generalnie jakbym nie zapisal getline czy cin w obrębie tych dwóch liniej to albo program pomijał wpisywanie danych w następnym pytaniu albo zapisywał niepełne odpowiedzi z brakującym słowem albo pominiętą linijką itd.

Zarówno w 1 jak i 2 przypadku korzystam jedynie z getline a nie getch.

KOD:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <algorithm>
#include <string>

using namespace std;

string temat, nick;
string tresc[5];
string odpA[5], odpB[5], odpC[5], odpD[5];
string poprawna[5];
string odpowiedz;
int punkty=0;

int main()
{
    int nr_linii=1;
    string linia;
    int nr_pytania=0;

    fstream plik;
    plik.open("Test wiedzy.txt",ios::in);

    if (plik.good()==false)
    {
        cout<<"Nie udalo sie otworzyc pliku!";
        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<<"Twoja odpowiedz: ";
        cin>>odpowiedz;

        transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::tolower);

        if (odpowiedz==poprawna[i])
        {
            cout<<"Dobrze! Zdobywasz punkt!"<<endl;
            punkty++;
        }
        else cout<<"Zle! Brak punktu! Poprawna odpowiedz: "<<poprawna[i]<<endl;

    }

    cout<<"Koniec quizu. Zdobyte punkty: "<<punkty;

    return 0;
}
0

Niestety zapisał mi się już kod autora jako własny na screenach, jedynie jest inny plik do odczytu, aczkolwiek i tak to nie zmienia sytuacji. Załączam jeszcze jak to wygląda po odpaleniu programu .
pominiete odp.PNG

1

Zgodnie z Twoim kodem, pierwsze dwie linijki pliku wejściowego powinny opisywać temat oraz nick; zdaje się, że w Twoim pliku tekstowym tego nie ma (a przynajmniej tak wygląda to na zrzucie ekranu).

0

Faktycznie na screenie nie ma coś widocznie w tym momencie kliknąłem ale jak wpisuje tak jak w pliku od autora ćwiczenia tj. pierwsza linijka temat "Test wiedzy" a w drugiej imie i nazwisko to nic nie zmienia
;/

W skrócie to przy tym samym kodzie ale wczytanym moim pliku .txt u mnie się wysypuje a przy pliku .txt od autora działała chociaż nie widzę różnic :|

Chyba, że kluczowe jest aby plik tekstowy również bym wygenerowany z programu? Chociaż poza podanymi momentami program wszystkie inne dane czyta mimo, że plik .txt stworzyłem ręcznie.

1

Gdzieś już widziałem to swicth case
To nie jest z tego pana, co nie umie i dlatego uczy ?

0

No nie wiem, ale dobrze jakby to wyszło teraz jak nie "stracilem" na nim jeszcze dużo czasu

0

Podejrzewam 2 problemy:

  1. W wierszu w którym masz podać poprawną odpowiedź podajesz a, b, c lub d zaś trzeba (wg kodu) powtórzyć ta odpowiedź
  2. W wierszu w którym masz podać poprawną odpowiedź używasz dużych liter np: Fasola zaś trzeba (wg kodu) napisać fasola

Zadanie totalnie anty dydaktyczne:

  1. Na siłę wsadzone użycie switch kiedy to generalnie należy unikać switch'a bo jest tym samym co drabinka if'ów.
  2. Nie wiadomo czemu w pliku podano nie używane wiersze nagłówkowe co zaciemnia zadanie.
  3. Zamiast zrobić tablicę odpABCD[4][5] a przy wyświetlaniu użyć pętle robi dokładnie na odwrót.
  4. Nie wiedzieć czemu wczytuje od razu cały plik do pamięci zamiast czytać go na bieżąco.

Moja propozycja pliku:

Pytanie 1
A1
B1
c1
D1
c

Pytanie 2
a2
B2
C2
D2
a

Pytanie 3
A3
B3
C3
d3
d

Pytanie 4
A4
b4
C4
D4
b

Pytanie 5
A5
B5
c5
D5
c

Oraz rozwiązania do tego pliku:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <string>
using namespace std;

int main()
{
	int score=0;
    ifstream file("Test0119.txt");
    if(!file)
    {
        cout<<"Nie udalo sie otworzyc pliku!";
        exit(0);
    }
    while(true)
    {
    	string line;
    	if(!getline(file>>ws,line)) break;
    	cout<<line<<endl;
    	for(int i=0;i<4;++i)
    	{
    		getline(file>>ws,line);
    		cout<<(char)('A'+i)<<". "<<line<<endl;    		
		}
    	file>>ws>>line;
        cout<<"Twoja odpowiedz (A,B,C,D): ";
    	char answer;
        cin>>answer;
        if((line.size())&&(toupper(line[0])==toupper(answer)))
        {
            cout<<"Dobrze! Zdobywasz punkt!";
            ++score;
        }
        else cout<<"Zle! Brak punktu! Poprawna odpowiedz: "<<line;
        cout<<endl<<endl;
    }
    file.close();
    cout<<"Koniec quizu. Zdobyte punkty: "<<score;
    return 0;
}
0

Dzięki! Faktycznie, po przeanalizowaniu Twoja propozycja Dragon jest dla mnie łatwiejsza, przy okazji poznałem trochę nowości :) Jedynie nie wiem czy dobrze sobie to przetworzyłem ale w momencie --> (toupper(line[0]) to "0" w line[0] jest dlatego, że linia 0 to pierwsza linia w pliku po odpowiedziach które są już zawarte w pętli?

No i na koniec pewnie to było już wałkowane nie raz, ale tak jak wyszło teraz, że w tej serii filmików, którą wstawiłem są takie kwiatki to co byście polecili bardziej rzetelnego? Dla samouka właśnie. Dzięki!

1

Ma ktoś linkna, do czegoś innego niż Zelent, żeby dać zainteresowanemu.
Już wiele razy było wykazane, że Kursy z tego źródła są szkodliwe (złe praktyki, poważne techniczne błędy, które nie są oczywiste). Nawet w tym filmiku widzę takie rzeczy.

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