So I'm working on a quiz game application, and one of the things I have to do is use StreamReader to read questions from a text file of the format

Question
Answer1
###Answer 2 (correct answer denoted by ###)
Answer3
Answer4
Question2
Answer1
Answer2
###Answer3
Answer4

and so on. I then have to display the question and said answers on a form, making sure not to display the ###. Basically I'm confused on how I should do this, as our teacher didn't go over StreamReader, and I'm entirely unsure of how I should get it to read a file, return an object, and then use that object to write the text on the form.

public TriviaQuestion ReadQuestion(): reads the input file and returns a new TriviaQuestion object.

And TriviaQuestion is as follows:

namespace QuizGame
{
    class TriviaQuestion
    {
        //attributes
        private string question;
        private string answerA;
        private string answerB;
        private string answerC;
        private string answerD;
        private string correctAnswer;

        //properties
        public string AnswerA { get; set; }
        public string AnswerB { get; set; }
        public string AnswerC { get; set; }
        public string AnswerD { get; set; }
        public string CorrectAnswer { get; set; }

    }
}

Any help here?

Recommended Answers

All 12 Replies

Are you allowed to pass anything into ReadQuestion? somehow you have to send the streamreader object in so it can maintain the position in the file each time.

Also, there's no way to access the private question variable in the TriviaQuestion class.

>Basically I'm confused on how I should do this, as our teacher didn't go over StreamReader.

Here is StreamReader class. Open a file and use ReadLine() method.

StreamReader sr=new StreamReader("file.txt");
   TriviaQuestion obj=new TriviaQuestion();
   ....

Hokay, I figured out most of it... but now when I run my form the questions and answers are all blank. I can't seem to find a problem in my code that would cause this. Can you guys look it over? Warning: incoming wall of code.

TriviaQuestion class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace QuizGame
{
    class TriviaQuestion
    {
        //attributes
        private string question;
        private string answerA;
        private string answerB;
        private string answerC;
        private string answerD;
        private string correctAnswer;

        //properties
        public string Question { get; set; }
        public string AnswerA { get; set; }
        public string AnswerB { get; set; }
        public string AnswerC { get; set; }
        public string AnswerD { get; set; }
        public string CorrectAnswer { get; set; }

        //constructor
        public TriviaQuestion(string question, string answerA, string answerB, string answerC, string answerD, string correctAnswer)
        {
            this.question = question;
            this.answerA = answerA;
            this.answerB = answerB;
            this.answerC = answerC;
            this.answerD = answerD;
            this.correctAnswer = correctAnswer;
        }
    }
}

TriviaGame class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace QuizGame
{
    class TriviaGame
    {
        //attributes
        private int questionAttempt;
        private int answersCorrect;
        public StreamReader questionGetter = new StreamReader("quiz.txt");

        //properties
        public int QuestionAttempt { get { return questionAttempt; } }
        public int AnswersCorrect { get { return answersCorrect; } }

        //methods
        //increments both answer counter if correct answer selected
        public void AddCorrectAnswer()
        {
            this.questionAttempt++;
            this.answersCorrect++;
        }
        //increments only attempted question counter if wrong answer selected
        public void AddIncorrectAnswer() { this.questionAttempt++; }
        //reads from input file and creates new TriviaQuestion object
        public TriviaQuestion ReadQuestion()
        {
           string[] inputStrings = new string[ 6 ];
            for ( int i = 0 ; i < 5 && !questionGetter.EndOfStream ; i++ )
            {
                inputStrings[ i ] = questionGetter.ReadLine();
            }
            for (int i = 1; i < 5; i++)
            {
                if (inputStrings[i].Substring(0, 2) == "###")
                {
                    inputStrings[5] = inputStrings[i].Trim('#');
                    inputStrings[i] = inputStrings[5];
                }
            }
            return new TriviaQuestion(inputStrings[0], inputStrings[1], inputStrings[2], inputStrings[3], inputStrings[4], inputStrings[5]);
        }
    }
}

QuizForm (my main form) code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace QuizGame
{
    public partial class QuizForm : Form
    {
        private TriviaQuestion currentQuestion;
        private TriviaGame game;
        public QuizForm()
        {
            InitializeComponent();
        }

        private void QuizForm_Load(object sender, EventArgs e)
        {
            game = new TriviaGame();
            currentQuestion = game.ReadQuestion();
            question.Text = currentQuestion.Question;
            answerA.Text = currentQuestion.AnswerA;
            answerB.Text = currentQuestion.AnswerB;
            answerC.Text = currentQuestion.AnswerC;
            answerD.Text = currentQuestion.AnswerD;
            attemptsLbl.Text = "Attempted: " + Convert.ToString(game.QuestionAttempt);
            correctLbl.Text = "Correct: " + Convert.ToString(game.AnswersCorrect);
        }

        private void nextBtn_Click(object sender, EventArgs e)
        {
            currentQuestion = game.ReadQuestion();
            question.Text = currentQuestion.Question;
            answerA.Text = currentQuestion.AnswerA;
            answerB.Text = currentQuestion.AnswerB;
            answerC.Text = currentQuestion.AnswerC;
            answerD.Text = currentQuestion.AnswerD;
            attemptsLbl.Text = "Attempted: " + Convert.ToString(game.QuestionAttempt);
            correctLbl.Text = "Correct: " + Convert.ToString(game.AnswersCorrect);
            selectBtn.Enabled = true;
            wrongNotif.Visible = false;
        }

        private void selectBtn_Click(object sender, EventArgs e)
        {
            selectBtn.Enabled = false;
            if (answerA.Checked == true)
            {
                if (answerA.Text == currentQuestion.CorrectAnswer)
                {
                    game.AddCorrectAnswer();
                }
                else
                {
                    game.AddIncorrectAnswer();
                    wrongNotif.Visible = true;
                }
            }
            if (answerB.Checked == true)
            {
                if (answerB.Text == currentQuestion.CorrectAnswer)
                {
                    game.AddCorrectAnswer();
                }
                else
                {
                    game.AddIncorrectAnswer();
                    wrongNotif.Visible = true;
                }
            }
            if (answerC.Checked == true)
            {
                if (answerC.Text == currentQuestion.CorrectAnswer)
                {
                    game.AddCorrectAnswer();
                }
                else
                {
                    game.AddIncorrectAnswer();
                    wrongNotif.Visible = true;
                }
            }
            if (answerD.Checked == true)
            {
                if (answerD.Text == currentQuestion.CorrectAnswer)
                {
                    game.AddCorrectAnswer();
                }
                else
                {
                    game.AddIncorrectAnswer();
                    wrongNotif.Visible = true;
                }
            }
        }

        private void quitBtn_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

I have no clue why my questions are all blank. Everything else functions properly.

Have you run it through the debugger?** That will be able to tell you exactly where you lost the data. Otherwise I'll take a closer look.

I'd make a private method for lines 24-31 (Quizform) and call it in the load method and in nextbtn_click.

In Triviagame from lines 33-44. What I would do is read the values into a temp, check if it's got # as the first character, if it does take the substring from 3 to the end and put that into the correct answer slot and where it belongs (a,b,c,d). Just a suggestion. That way you don't have to loop twice.

**if you hate the debugger, which you shouldn't :) but if so pepper your code with System.Diagnostics.Debug.WriteLine() statements and it will show up in the output window of the IDE (or output them to a temporary textbox on your form itself)

*sigh* Ok now it seems like nothing is even getting assigned somehow. All my q's and a's are blank, and even when I select a correct answer it still says it's wrong, plus I'm getting an unhandled exception at EOF even though I put the code in my streamreading method to make it stop at EOF...

I'm in the process of recreating your form.
Are answerA thru D radio buttons?
What is wrongNotif?

I made the following changes to the TriviaQuestion class, see if substituting this one in helps:

public class TriviaQuestion
    {
        private string question;
        private string answerA;
        private string answerB;
        private string answerC;
        private string answerD;
        private string correctAnswer;

         //properties
        public string Question { get { return question; } set { question = value; } }
        public string AnswerA { get { return answerA; } set { answerA = value; } }
        public string AnswerB { get { return answerB; } set { answerB = value; } }
        public string AnswerC { get { return answerC; } set { answerC = value; } }
        public string AnswerD { get { return answerD; } set { answerD = value; } }
        public string CorrectAnswer { get { return correctAnswer; } set { correctAnswer = value; } }
 //explicitly tell it to get and set the private member variables
    }

You have it trying to pull data out of answerA, etc. when all your getters and setters (the default ones) are capable of is getting and setting the properties like AnswerA, etc.

I'm in the process of recreating your form.
Are answerA thru D radio buttons?
What is wrongNotif?

Yes, they are radios grouped so only one can be selected.
wrongNotif is a label that appears if the answer is wrong in big red letters.

I made the following changes to the TriviaQuestion class, see if substituting this one in helps:

public class TriviaQuestion
    {
        private string question;
        private string answerA;
        private string answerB;
        private string answerC;
        private string answerD;
        private string correctAnswer;

         //properties
        public string Question { get { return question; } set { question = value; } }
        public string AnswerA { get { return answerA; } set { answerA = value; } }
        public string AnswerB { get { return answerB; } set { answerB = value; } }
        public string AnswerC { get { return answerC; } set { answerC = value; } }
        public string AnswerD { get { return answerD; } set { answerD = value; } }
        public string CorrectAnswer { get { return correctAnswer; } set { correctAnswer = value; } }
 //explicitly tell it to get and set the private member variables
    }

You have it trying to pull data out of answerA, etc. when all your getters and setters (the default ones) are capable of is getting and setting the properties like AnswerA, etc.

Okay, that fixed it. I thought that's what default getsetters did... apparently not.
Now the only problem is the correct answer still shows up on the label with the ### in front of it, and even if I choose the right answer it says it's wrong...

if (inputStrings[i].Substring(0, 2) == "###") Take a look at the definition of substring and you'll see why this is impossible. I missed it before...

if (inputStrings[i].Substring(0, 2) == "###") Take a look at the definition of substring and you'll see why this is impossible. I missed it before...

Wow thanks... Changing the 2 to a 3 fixed EVERYTHING, it works perfectly now. I thought that was the end index, not the length of the substring. Thanks a lot for all the help.

I thought that was the end index, not the length of the substring.

No worries. It's this kind of "gotcha" that can be the most frustrating because it goes unchecked.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.