Problem z prostym programem

0

Witam, otóż chciałem zrobić program dzięki któremu mógłbym uczyć się języka. Miałoby to polegać na tym, że jest zestaw pytań w pliku txt. Program losuje pytanie, w którym jest krótki kod i losowo wygenerowane miejsce w którym brakuje znaku i zastępuje je znakiem zapytania. Ja wpisuje czego brakuje, program albo mówi dobrze albo źle i daje kolejne pytanie. Wydawało mi się to dobrym pomysłem bo takim, który by mnie czegoś nauczył i takim, na który mnie stać. Jednak nie dałem rady kompletnie chat gpt także nie pomógł a tylko namieszał. Jest problem z wygenerowaniem miejsca w którym znika znak. To co udało mi się sklecić po dobrych 3 godzinach daje niżej, a także plik z pytaniami. Nie wiedziałem co zrobić więc przyszedłem tutaj. Liczę na waszą pomoc na prawdę już nie wiem co mam zrobić. Program:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <random>

using namespace std;

// Structure representing a question and its answer
struct Question {
    string question;
    string code;
    char missingChar;
};

// Function to read questions from a file
vector<Question> readQuestionsFromFile(const string& filename) {
    ifstream file(filename);
    vector<Question> questions;
    if (file.is_open()) {
        string line;
        while (getline(file, line)) {
            size_t pos = line.find("|");
            if (pos != string::npos && pos > 0 && pos < line.length() - 1) {
                Question q;
                q.question = line.substr(0, pos);
                q.code = line.substr(pos + 1);
                questions.push_back(q);
            }
        }
        file.close();
    } else {
        cerr << "Unable to open the file " << filename << endl;
    }
    return questions;
}

// Function to replace a random non-space character with '?'
void replaceRandomNonSpaceWithQuestionMark(Question& q) {
    // Find all non-space characters
    vector<size_t> nonSpaceIndices;
    for (size_t i = 0; i < q.code.length(); ++i) {
        if (q.code[i] != ' ') {
            nonSpaceIndices.push_back(i);
        }
    }

    if (!nonSpaceIndices.empty()) {
        // Choose a random index
        random_device rd;
        mt19937 gen(rd());
        uniform_int_distribution<> dis(0, nonSpaceIndices.size() - 1);
        size_t randomIndex = nonSpaceIndices[dis(gen)];

        // Replace the character at the random index with '?'
        q.missingChar = q.code[randomIndex];
        q.code[randomIndex] = '?';
    }
}

int main() {
    const string questionsFile = "pytania.txt";
    vector<Question> questions = readQuestionsFromFile(questionsFile);

    if (questions.empty()) {
        cout << "Brak pytań. Sprawdź plik " << questionsFile << endl;
        return 1;
    }

    while (true) {
        for (size_t i = 0; i < questions.size(); ++i) {
            // Display the question
            cout << "Pytanie: " << questions[i].question << endl;

            // Display the code
            cout << "Kod: " << questions[i].code << endl;

            // Replace a random non-space character with '?'
            replaceRandomNonSpaceWithQuestionMark(questions[i]);

            // Display the code with the missing character
            cout << "Kod (z brakującym znakiem): " << questions[i].code << endl;

            // Get user's answer
            char userAnswer;
            cout << "Czego brakuje w kodzie? ";
            cin >> userAnswer;

            // Check user's answer
            if (userAnswer == questions[i].missingChar) {
                cout << "Dobrze!" << endl;
            } else {
                cout << "Źle. Poprawna odpowiedź to: " << questions[i].missingChar << endl;
            }

            // Wait for the next question
            cout << "Naciśnij Enter, aby przejść do kolejnego pytania...";
            cin.ignore(); // Ignore extra Enter
            cin.get(); // Wait for Enter
        }
    }

    return 0;
}

Plik z odpowiedziami:
obliczanie kwadratu liczby int a; a = a*a; cout a;
wybieranie losowej liczby z zakresu srand(time(NULL)); int randomNumber = rand() % range + minNumber; cout randomNumber;
obliczanie sumy elementów tablic |int sum = 0; for(int i = 0; i < size; i++) { sum += array[i]; } cout sum;

0

Popraw formatowanie w poście pls bo nie działa za dobrze

Jest problem z wygenerowaniem miejsca w którym znika znak.

Jaki problem dokładnie?

Program się kompiluje, czy nie? Jeśli tak, i go uruchamiasz, co się dzieje? Po czym poznajesz, że nie działa jak należy?

0

Tak program się kompiluje, gdy uruchamiam program w zasadzie wszystko działa dobrze poza tym, że znak zapytania, który powinien pojawiać się w losowym miejscu krótkiego kodu z pytania i zastępować tym samym losowo wybrany znak, robi to zawsze w tym samym miejscu.

Żeby to zobrazować to podam przykład:

mamy tu polecenie i znak zapytania, który pojawił się "losowo":
obliczanie kwadratu liczby|int a; a = a*?; cout a;|=.

jak widać znak zapytania jest w miejscu "a". problem polega na tym, że gdy natrafię na to samo pytanie po raz drugi to znak zapytania zamiast być w innym miejscu jest w dokładnie tym samym. I jest tak z każdym pytaniem. Mimo że znak w różniących się od siebie pytaniach faktycznie jest w różnych miejscach to jednak gdy natrafię na to samo pytanie to jest w tym samym.

0

Super, to jest ważna wskazówka. Brzmi jakby generator liczb pseudolosowych za każdym razem był inicjowany tą samą wartością, skoro zawsze zdaje się, że generuje to samo

Tu

random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dis(0, nonSpaceIndices.size() - 1);
size_t randomIndex = nonSpaceIndices[dis(gen)];

się musi dziać coś dziwnego. To tak na oko, bo na tę chwilę nie mam dostępu do komputera.

Dalej masz w przykładach kodu prostsze rozwiązanie na generowanie lososej wartości:

srand(time(NULL)); int randomNumber = rand() % range + minNumber;

Może spróbuj tego użyć zamiast tego wyżej?

0

Nic nie pomogło niestety, dodatkowo nie wiem czy to się wcześniej działo ale po kilku pytaniach program już sam nie wie gdzie jest znak zapytania i daje niepoprawne odpowiedzi

2
Michał Bursztyn napisał(a):

Nic nie pomogło niestety, dodatkowo nie wiem czy to się wcześniej działo ale po kilku pytaniach program już sam nie wie gdzie jest znak zapytania i daje niepoprawne odpowiedzi

No to czas na debugging, w najprostszej formie będzie to tzw. "dupa debugging"

Musisz dociec która część kodu nie działa tak, jak tego oczekujesz. A potem dociec, dlaczego.

A skąd masz wiedzieć co tam się dzieje w środku?

Najprostsza metoda - dodaj wypisywanie do konsoli:

  • jaka funkcja się teraz wykonuje (info przy wejściu do funkcji)
  • jakie argumenty były podane do funkcji
  • jakie są wartości zmiennych, szczególnie po ich modyfikacji
    Itd.

Chcesz widzieć co się dzieje i w jakiej linijce kodu

Np. "teraz odpala się replaceRandomNonSpaceWithQuestionMark, dla wartości q = ...", "linijka 69: nonSpaceIndices zawiera [21, 37]" itd. itp.

Mozolnie, ale skutecznie dowiesz się co się wykonuje krok po kroku i zweryfikujesz źródło problemu

0

Dzięki za wytłumaczenie na spokojnie jak już może zauważyłeś nie jestem zbyt ogarnięty jak na razie i sam bym nie doszedł co jest nie tak, ale zrobiłem jak powiedziałeś i w 15 minut po problemie

0
Michał Bursztyn napisał(a):

Dzięki za wytłumaczenie na spokojnie jak już może zauważyłeś nie jestem zbyt ogarnięty jak na razie i sam bym nie doszedł co jest nie tak, ale zrobiłem jak powiedziałeś i w 15 minut po problemie

Nie ma za co i fajnie, że udało się naprawić

Z ciekawości, co było problemem i jak to naprawiłeś?

1

Problem był bardzo prosty aż dziwne że się nie domyśliłem.

Losowanie działało poprawnie, problem w tym, że program zamiast wstawiać znak zapytania przed każdym przykładem robił to tylko przy starcie programu. Przez to przy poszczególnych przykładach co prawda był w różnych miejscach, ale gdy trafiało na to samo po raz drugi to robił losowanie, ale nie wstawiał znaku i tylko podstawiał to co już wcześniej sobie napisał

Myślałem, że już tego nie rozwiąże, a tym czasem to taki głupi błąd

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