Ren
Ren

Reputation: 53

How to change a bool from true to false using an if statement that has user input as its condition?

Header file:

#include <iostream>
#include <string>

std::string correctText = "\nCorrect! +";
std::string incorrectText = "False!\n";
std::string answer = "paris";

bool correct = true;

int score;

void scoreSystem() {
    if (correct == true) {
        std::cout << correctText;
        score++;
    }
    else {
        std::cout << incorrectText;
    }
}

Source file:

#include <iostream>
#include <string>
#include "Primitive Quiz Header.h"

int main() {
    std::cout << "What is the capital of france?\n\n";
    if (std::cin >> answer) {
        correct = true;
    }
    else {
        correct = false;
    }
    scoreSystem();
    std::cout << score;
    return 0;
}

The code is intended to use the bool correct as a way to tell the scoreSystem() function if it should increment the score integer and output the string correctText, or output the incorrectText string. If the user answers correctly, correct should be true; false if answered incorrectly.

However, no matter what the user enters, correct remains true and the scoreSystem() always outputs with the correctText string and increments the score integer.

Example:

What is the capital of france?

gruh \\example of incorrect user input

Correct! +1

I don't understand what exactly is preventing correct from changing. Is it the scoreSystem() function, or how the user inputs their answer in main()?

Upvotes: 0

Views: 97

Answers (1)

Jerry Coffin
Jerry Coffin

Reputation: 489988

A statement like if (x) y = true; is clumsy, and should generally be avoided. If x is already a bool, then you can usually use y = x;. If it's not already a bool, then you may want y = static_cast<bool>(x); instead (or, for people who prefer parsimony, y = !!x;).

It's also rarely useful to ask only a single question. Usually you'd want something along this general line:

struct Question {
    std::string question;
    std::string answer;

    bool correct(std::string const &user_answer) { 
       return user_answer == answer;
    }

    friend std::ostream &operator<<(std::ostream &os, Question const &q) { 
        return os << q.question;
    }
};

Then you could have a number of questions and answers, something like this:

const std::vector<Question> questions { 
    { "What is the capitol of France?", "Paris" },
    { "what is the capitol of Great Britain?", "London"},
    { "What is deepest lake on earth?", "Baikal"}
    // ...
};

int main() { 
    int score = 0;

    for (auto const &q : questions) {
        std::cout << q;
        std::string user_answer;
        std::cin >> user_answer;
        bool correct = q.correct(user_answer);
        std::cout << std::boolalpha << correct;
        score += correct;
    }
    std::cout << "You got: " << score << " questions right\n";
}

This has one minor defect though. It prints out true and false instead of "\nCorrect! +" and "\nFalse!". Fortunately, there's a way to fix that too.

#include <string>
#include <vector>
#include <locale>
#include <ios>
#include <iostream>

class TestPunct : public std::numpunct< char > {
protected:
    char do_decimal_point() const { return ','; }
    char do_thousands_sep() const { return '.'; }
    std::string do_grouping() const { return "\3"; }
    std::string do_truename() const { return "\nCorrect!\n";  }
    std::string do_falsename() const { return "\nFalse\n"; }
};

struct Question {
    std::string question;
    std::string answer;

    bool correct(std::string const &user_answer) const { 
       return user_answer == answer;
    }

    friend std::ostream &operator<<(std::ostream &os, Question const &q) { 
        return os << q.question << "? ";
    }
};

const std::vector<Question> questions { 
    { "What is the capitol of France", "Paris" },
    { "what is the capitol of Great Britain", "London"},
    { "What is deepest lake on earth", "Baikal"}
    // ...
};

int main() { 
    std::cout.imbue(std::locale(std::locale(), new TestPunct));

    int score = 0;

    for (auto const &q : questions) {
        std::cout << q;
        std::string user_answer;
        std::cin >> user_answer;
        bool correct = q.correct(user_answer);
        std::cout << std::boolalpha << correct;
        score += correct;
    }
    std::cout << "You got: " << score << " questions right\n";
}

Result:

$ ./a.out
What is the capitol of France? Paris

Correct!
what is the capitol of Great Britain? London

Correct!
What is deepest lake on earth? Baikal

Correct!
You got: 3 questions right

Upvotes: 3

Related Questions