Wątek przeniesiony 2016-06-14 10:34 z C/C++ przez ŁF.

Wysypujący się program.

0

Witam!

Jestem totalnie nowy w C++ i chciałem tak dla własnej satysfakcji stworzyć sobie quiz, niestety wysypuje się na drugim pytaniu. Kod źródłowy quizu:

#include <iostream>
#include <conio.h>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <string>

using namespace std;

int punkty = 0, i;

string baza();
string pytanie();
string wybor();
string koniec();
string pyt[40], odp[40], odpowiedz;

char t, przycisk, dowolny;

int main()
{
    baza();

    // QUIZ //
    cout << "Wybierz temat:" << endl;
    cout << "1. Sport" << endl;
    cout << "2. Religie" << endl;
    cout << "3. Nauki scisle" << endl;
    cout << "4. Historia Polski XIX i XX wieku" << endl << endl;

    cout << "Aby wybrac temat, wpisz numer jemu odpowiadajacy: "; t = getch();
    wybor();

    return 0;
}


// FUNCKJE

string baza() // BAZA PYTAŃ I ODPOWIEDZI


string pytanie()
{
        system("cls");
        cout << pyt[i] << endl << "Wpisz odpowiedz: "; cin >> odpowiedz;

        if(odpowiedz == odp[i]) {punkty++;} 
        else {cout << "Poprawna odpowiedz: " << odp[i];}

        transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::toupper); if(odpowiedz == odp[i]) {punkty++;} else{}
        system("cls");
}

string wybor()
{
    if(t == '1') {for(int i = 0; i < 10; i++) {pytanie();}}
    if(t == '2') {for(int i = 10; i < 20; i++) {pytanie();}}
    if(t == '3') {for(int i = 20; i < 30; i++) {pytanie();}}
    if(t == '4') {for(int i = 30; i < 40; i++) {pytanie();}}
}

Podejrzewam, że program się wysypuje z powodu tej ostatniej funkcji, ale nie wiem, jak to zmienić. Prosiłbym o podpowiedź lub o jedną linię kodu (chociaż sam wolałbym do tego dojść), która nakieruje mnie na rozwiązanie.

3

zmienna i globalna jest nie zainicjalizowana. Przestan uzywac zmiennych globalnych to problem zniknie

edit. Tak dawno nie uzywalem zmiennych globalnych (bo jest to zle) ze zapomnialem, ze bedzie zainicjalizowana zerem (w tym przypadku) nadal. Usun globalne zmienne to problem zniknie. Do tego nazywaj zmienne sensownie

4

Nie rozumiem dlaczego sądzisz że i z pytanie to jest i z pętli w wybor.

4

Jeśli definiujesz funkcję jako zwracającą Typ to musisz ten typ zwrócić. Masz tu UB.

5

Porada dla Ciebie na czas, kiedy nie wiesz co robisz:

  • Zamiast type array_name[size] używaj std::array<type, size> array_name;
  • zamiast array_name[index] używaj array_name.at(index)

Te zmiany pozwolą Ci wyłapać wszystkie głupie błędy związane z odwoływaniem się do nieistniejących elementów.

PS. nie używaj zmiennych globalnych.

0

Każdy pisze, żebym nie używał zmiennych globalnych. Może mi ktoś wyjaśnić dlaczego? Przepraszam, że tak głupio pytam, ale jestem newbie w tym temacie.

7
  1. utrudniasz czytanie kodu innym. Widząc zmienną globalną nie masz pojęcia jaki jest jej udział w wykonaniu innych funkcji. Czy jeśli zmienię ImieStefana to czy funkcja mojsinus(x) będzie zwracać inne wyniki? Z perspektywy czytającego każda zmienna globalna to dodatkowy parametr do wszystkich istniejących funkcji.
  2. utrudniasz testowanie. Zamiast sprawdzić, że mojsinus(π) == 0, musisz zastanowić się jak poustawiać zmienne globalne, aby otrzymać poprawny wynik
  3. utrudniasz/uniemożliwiasz wielowątkowość. Jeśli podczas swojej pracy operujesz na zmiennych globalnych, a jakaś inna funkcja z innego wątku również używa tych samych...
3

Wyobraź sobie że masz duży, duży projekt. Nazwy mogą się zacząć w pewnym momencie pokrywać. Przykładowa sytuacja: masz zmienną globalną faultId, oraz funkcję która przyjmuje parametr o takiej samej nazwie. W procesie refaktoringu usuwasz go z funkcji, ale przez nieostrożność nie usunąłeś go z wszystkich wystąpień w funkcji - kompilator Cię o tym nie poinformuje bo z jego perspektywy wszystko jest OK, a u Ciebie w programie zaczynają się cuda :)
Generalnie sytuacja jest trochę nadmuchana, ale jak najbardziej możliwa. Chodzi przede wszystkim o utrzymanie porządku w kodzie.

5

Dodałbym jeszcze:
4. dobrą praktyką jest największe możliwe ograniczanie scope każdego obiektu
5. utrudniasz kompilatorowi optymalizacje kodu

0

Łał, dziękuję serdecznie za tak szybkie odpowiedzi. Teraz już będę wiedział, dlaczego nie warto używać zmiennych globalnych dla funkcji.

0

Nie tylko dla funkcji.
https://4programmers.net/Forum/1230899

0

Po "lekkiej" zmianie kodu quiz zaczął poprawnie działać, ale pojawił się kolejny problem, mianowicie doszły mi trzy (prawie) bliźniacze funkcje. Jak mogę użyć argumentów funkcji, aby jedna funkcja zawierała wszystkie cztery?

Kod:

string pytanie_1()
{
        for(int i = 0; i < 10; i++)
        {
            system("cls");
            cout << pyt[i] << endl << "Wpisz odpowiedz: "; cin >> odpowiedz;
            transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::toupper);

            if(odpowiedz == odp[i]) {punkty++;} else{}
            system("cls");
        }

        cout << "Koniec quizu. Zdobyte punkty: " << punkty << endl;
        cout << "--------------------------------" << endl << endl;
}

string pytanie_2()
{
        for(int i = 10; i < 20; i++)
        {
            system("cls");
            cout << pyt[i] << endl << "Wpisz odpowiedz: "; cin >> odpowiedz;
            transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::toupper);

            if(odpowiedz == odp[i]) {punkty++;} else{}
            system("cls");
        }

        cout << "Koniec quizu. Zdobyte punkty: " << punkty << endl;
        cout << "--------------------------------" << endl << endl;
}

string pytanie_3()
{
        for(int i = 20; i < 30; i++)
        {
            system("cls");
            cout << pyt[i] << endl << "Wpisz odpowiedz: "; cin >> odpowiedz;
            transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::toupper);

            if(odpowiedz == odp[i]) {punkty++;} else{}
            system("cls");
        }

        cout << "Koniec quizu. Zdobyte punkty: " << punkty << endl;
        cout << "--------------------------------" << endl << endl;
}

string pytanie_4()
{
        for(int i = 30; i < 40; i++)
        {
            system("cls");
            cout << pyt[i] << endl << "Wpisz odpowiedz: "; cin >> odpowiedz;
            transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::toupper);

            if(odpowiedz == odp[i]) {punkty++;} else{}
            system("cls");
        }

        cout << "Koniec quizu. Zdobyte punkty: " << punkty << endl;
        cout << "--------------------------------" << endl << endl;
}

string wybor()
{
    if(t == '1') return pytanie_1();
    if(t == '2') return pytanie_2();
    if(t == '3') return pytanie_3();
    if(t == '4') return pytanie_4();
} 
1

Najpierw to: http://format.krzaq.cc/ (styl file), bo ten kod to facepalm pod względem formatowania.

0
string pytanie_1()
{
    for (int i = 0; i < 10; i++)
    {
        system("cls");
        cout << pyt[i] << endl << "Wpisz odpowiedz: ";
        cin >> odpowiedz;
        if (odpowiedz == odp[i])
        {
            punkty++;
        }
        else
        {
            cout << "Poprawna odpowiedz: " << odp[i];
        }
        transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::toupper);
        system("cls");
    }

    cout << "Koniec quizu. Zdobyte punkty: " << punkty << endl;
    cout << "--------------------------------" << endl << endl;
}

string pytanie_2()
{
    for (int i = 10; i < 20; i++)
    {
        system("cls");
        cout << pyt[i] << endl << "Wpisz odpowiedz: ";
        cin >> odpowiedz;
        if (odpowiedz == odp[i])
        {
            punkty++;
        }
        else
        {
            cout << "Poprawna odpowiedz: " << odp[i];
        }
        transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::toupper);
        if (odpowiedz == odp[i])
        {
            punkty++;
        }
        else
        {
        }
        system("cls");
    }

    cout << "Koniec quizu. Zdobyte punkty: " << punkty << endl;
    cout << "--------------------------------" << endl << endl;
}

string pytanie_3()
{
    for (int i = 20; i < 30; i++)
    {
        system("cls");
        cout << pyt[i] << endl << "Wpisz odpowiedz: ";
        cin >> odpowiedz;
        if (odpowiedz == odp[i])
        {
            punkty++;
        }
        else
        {
            cout << "Poprawna odpowiedz: " << odp[i];
        }
        transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::toupper);
        if (odpowiedz == odp[i])
        {
            punkty++;
        }
        else
        {
        }
        system("cls");
    }

    cout << "Koniec quizu. Zdobyte punkty: " << punkty << endl;
    cout << "--------------------------------" << endl << endl;
}

string pytanie_4()
{
    for (int i = 30; i < 40; i++)
    {
        system("cls");
        cout << pyt[i] << endl << "Wpisz odpowiedz: ";
        cin >> odpowiedz;
        if (odpowiedz == odp[i])
        {
            punkty++;
        }
        else
        {
            cout << "Poprawna odpowiedz: " << odp[i];
        }
        transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::toupper);
        if (odpowiedz == odp[i])
        {
            punkty++;
        }
        else
        {
        }
        system("cls");
    }

    cout << "Koniec quizu. Zdobyte punkty: " << punkty << endl;
    cout << "--------------------------------" << endl << endl;
}

string wybor()
{
    if (t == '1')
        return pytanie_1();
    if (t == '2')
        return pytanie_2();
    if (t == '3')
        return pytanie_3();
    if (t == '4')
        return pytanie_4();
}
0

(jak dla mnie to ni epowinno sie kompilowac, bo ni zwracasz nic ze swoich funkcji)

string pytanie(int start)
{
        for(int i = start+1; i < (start+1 * 10); i++)
        {
            system("cls");
            cout << pyt[i] << endl << "Wpisz odpowiedz: "; cin >> odpowiedz;
            transform(odpowiedz.begin(), odpowiedz.end(), odpowiedz.begin(), ::toupper);
 
            if(odpowiedz == odp[i]) {punkty++;} else{}
            system("cls");
        }
 
        cout << "Koniec quizu. Zdobyte punkty: " << punkty << endl;
        cout << "--------------------------------" << endl << endl;
}

wywolujesz na zasadzie

if(t == '1') return pytanie(0);

ale oba kody (Twoj i ta propozycja ktora jest na gorze) jest po prostu bardzo brzydka. Tak w normalnym programowaniu sie nie robi

0

Wiem, że te kody, które wysłałem nie wygrają Miss Universe, ale na początku muszę się nauczyć, jak to w ogóle działa, a później chciałbym się zabrać za estetykę pracy.

0

Zasady "higieny" kodu są pierwszą rzeczą, którą powinieneś poznać. Wyobraź sobie naukę gotowania zaczynaną od stwierdzenia "później będę się martwił o czyste naczynia i ręce, na razie chcę zrobić kilka potraw".

0

No, w sumie racja, ale strasznie ciężko jest mi na chwilę obecną ułożyć to w jakąś sensowną kompozycję.

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