Struktura Test c++

0

Witam, miałem już podobny problem na tym forum aczkolwiek mój projekt okazał się lekko zły i muszę go poprawić. Czy ktoś może ocenić mój dotychczasowy kod(póki co parę linijek, chciałbym go regularnie aktualizować idąc krok po kroku z wyznaczonymi zadaniami). Mam tylko na wstępie jedno pytanie.

Czy powinienem projekt od razu pisać z podziałem na .h, .cpp itd, czy mogę napisać sobie wszystko w jedynym pliku a wszystko podzielić kiedy już skończę?

Moje zadanie polega na czymś takim:

Create structure Task, containing the information about the test question in the fields: a question, five variants of the answer, a correct answer number, a number of points for a correct answer and method to display a question (struct with public data-members for simplicity, it can be defined inside next class).

Kod który stworzyłem do tej pory:

#include <iostream> 
#include <string>
#include <vector>
using namespace std;

struct Task
{
	char guess;//będzie przyjmowało odpowiedź z klawiatury(a,b,c,d lub e)
	int total;//będzie sumowało liczbę pkt z testu
    string Question_Text;//pytanie
    string answer_1;//odp a
    string answer_2;//odp b
    string answer_3;//odp c
    string answer_4;//odp d
    string answer_5;//odp e
    char correct_answer;//wskazana prawidłowa odp w pytaniu
    int Question_Score;//liczba pkt za prawidłową odpowiedź
    
    
    public :Task(string q, string a1, string a2, string a3, string a4, string a5, char ca)//konstruktor do dodawania pytań
    {
    Question_Text = q;
    answer_1 = a1;
    answer_2 = a2;
    answer_3 = a3;
    answer_4 = a4;
    answer_5 = a5;
    correct_answer = ca;
    Question_Score = 5;//w konstruktorze pominąłem int qs, tylko na sztywno przypisałem od razu 5pkt za prawidłową odpowiedź, bo tak będzie punktowana w każdym pytaniu.(mam nadzieje że tak można).
	}
	
	void showQuestion(); //inicjacja metody wyswietlajacej pytanie
};

	void Task::showQuestion() //metoda wyswietlajaca pytanie
{
    cout << "\n";
    cout << Question_Text << "\n";
    cout << "a. " << answer_1 << "\n";
    cout << "b. " << answer_2 << "\n";
    cout << "c. " << answer_3 << "\n";
    cout << "d. " << answer_4 << "\n";
    cout << "e. " << answer_5 << "\n";
    cout << "\n";
}
    
int main(){
	
	return 0;
}

Znając moje umiejętności w C++, domyślam się że już teraz gdzieś popełniłem błąd, dlatego wolę iść kroczek po kroczku. Czy póki co jest coś źle?

2
  1. "Public:" jest niepotrzebne, bo domyślnie w strukturze dostęp jest publiczny, a nie ma wcześniej "private" ani "protected".
  2. Przestaw się na pracę z vectorami, to długość kodu skróci się o połowę i nie będziesz musiał go dodawać, gdy będziesz chciał coś zmienić. W funkcji showQuestion, aby wypisywać literki zrób coś takiego:
    void Task::showQuestion() 
{
    cout << endl;
    cout << Question_Text << "\n";
    int ascii_value = 0x61; //kod ascii 'a'; patrz na wpis niżej, gdzie jest łatwiejsza wersja 
for (string answer : answers) //zakładam, że w strukturze masz vector<string> answers;
{
    	char index_character = ascii_value;
    	cout << index_character << ". " << answer << endl;
		ascii_value++;
}
}
  1. Co do podziału. Możesz to zrobić później, tylko po co, jak i tak wiesz, że będziesz to robić?
  2. Co do komentarzy:
    char guess;//będzie przyjmowało odpowiedź z klawiatury(a,b,c,d lub e)
    int total;//będzie sumowało liczbę pkt z testu

To są zmienne, więc one nie będą nic przyjmować ani sumować. Od tego są funkcje. Zmienne mogą co najwyżej coś przechować i same ich nazwy powinny mówić co.

2

Nie trzeba tu używać kodu ASCII (zwłaszcza hexa). Wystarczy znak:

#include <iostream>
#include <vector>
using namespace std;

int main() {
	char c = 'a';
	vector<string> answers = {"zielony", "czerwony", "niebieski"};
	for(const auto &answer: answers) {
		cout << endl << c << ". " << answer;
		c++;
	}
	return 0;
}

wynik:

a. zielony
b. czerwony
c. niebieski

http://ideone.com/NrOcRB

(kody ASCII nie są używane np. na mainframe i są tam zupełnie inne kody znaków)

0

Mam pytanie dotyczące tych wektorów, bo nie miałem ich za dużo na zajęciach. Dopiero koleje polecenie(dalszy ciąg projektu) opiera się na wektorach(będę musiał wszystkie pytania stworzone wpakować do wektora i wtedy na nich działać). Niestety moja nauczycielka jest taka, że tak jak wygląda jej polecenie, tak na sztywno ma być zrobiony jej projekt..czy mogę kontynuować ten projekt tak jak zacząłem? w sensie że pytania tworzone za pomocą konstruktora etc, stworzone 5 stringów przyjmujące odpowiedzi etc..

Bo główne pytanie się opiera na tym, czy przechowywanie odp w wektorach itd mi coś zmieni, czy tylko i wyłącznie skróci kod?

1

Ten kod co masz teraz to jest akceptowalny tylko jeśli jesteś w szkole podstawowej.
Zadanie masz po angielsku, więc wnioskuję że musisz trochę się jednak nad tym pochylić.
Zamiast std::vector możesz użyć zwykłej tablicy.

Czyli zamień:

vector<string> answers;

na

string answers[5];

https://www.tutorialspoint.com/cprogramming/c_arrays.htm

to będzie bolesne, ale da się zrobić.

0

Właśnie jestem na erazmusie, więc pochylać za bardzo się nie muszę, a nawet bardziej muszę napisać słowo w słowo tak jak jest polecenie..jeden projekt już napisałem, dotyczący exception class, teraz mi pozostał ten, trochę dłuższy..To jak, mógłbym próbować kontynuować w sposób który zacząłem i liczyć na pomoc czy nie bardzo, bo jest to zbyt banalny sposób?

1

Możesz spróbować w ten sposób co masz, ale jeśli nie teraz to w następnym zadaniu prowadzący może zrobić taki ruch przy którym się rozpłaczesz.

Przykład z życia:
Ktoś na studiach miał do zrobienia mnożenie macierzy. Zrobił przypadki 2x2, 3x3 (tj. maks 27 operacji bez pętli).
Prowadzący poprosił o przemnożenie macierzy... 4x5 (tj. np. 4x5 * 5x4 = 65 operacji). I dla autora programu było to nie do przeskoczenia.

Tutaj może być podobnie - prowadzący poprosi o wersję z 20 pytaniami i może przy tej funkcjonalności nie będziesz miał problemu, ale dojdzie jakaś logika i wysiądziesz z liczbą if-ów.
Spróbuj ten program napisać tak żeby to 5 można było zmieniać przynajmniej przed kompilacją na dowolną liczbę (czyli tablice lub vectory plus pętle).

1

Wrzucam to, co posłałem w odpowiedzi PW:

#include <iostream>
#include <array>
#include <string>
#include <sstream>
using namespace std;
 
string prettify_index(size_t idx) {
    return { static_cast<char>('a'+idx) };
}
 
size_t unprettify_index(string const &sidx) {
    return static_cast<size_t>(sidx[0]-'a');
}
 
struct quiz {
    string question;
    string proper_answer;
    array<string, 5> answers;
 
    quiz(string const &question, string const &proper_answer, decltype(answers) const &answers):
        question(question),
        answers(answers),
        proper_answer(proper_answer)
    {}
 
    string pretty_string() const {
        stringstream out;
        out << "Pytanie:\n\t" << question << endl
            << "Możliwe odpowiedzi:" << endl;
 
        for(auto i = 0u; i < answers.size(); ++i) {
            out << "\t" << prettify_index(i) << ". " << answers[i] << endl;
        }
 
        return out.str();
    };
 
    bool validate(string const &answer) const {
        return proper_answer == answer;
    }
 
    bool validate(size_t idx) const {
        return proper_answer == answers[idx];
    }
};
 
int main() {
    quiz q {
        "Stolica Polski?",
        "Warszawa",
        {
            "Warszawa",
            "Poznań",
            "Kraków",
            "Gdańsk",
            "Toruń"
        }
    };
 
    cout << q.pretty_string();
 
    cout << "Twoja odpowiedź:\n";
    string answer;
    cin >> answer;
    cout << "\t" << (q.validate(unprettify_index(answer))? "Poprawna!" : "Niepoprawna.");
 
    return 0;
}

https://ideone.com/iQRN3e
https://ideone.com/CDrwQp
https://ideone.com/JSJJh3
https://ideone.com/INRNkK

Notka: jeśli podasz niepoprawne dane, program się wykrzaczy. Na potrzeby idiotoodporności sprawdzaj zakresy.

0

Wielkie dzięki!! Zaczynam analizę kodu już teraz, resztę dokończę jutro i później będę dalej kontynuował pisanie. Dziękuje wszystkim którzy starali się udzielić pomocy!

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