1

I started learning some basics of C++ and I wanted to write some code to practices what I've learned. I wanted to make a class and some functions. It's supposed to be a title screen to start a text game, except there is no game...yet :P

Whenever I enter 1 to start so it displays "Good Work" it just does nothing after I hit enter.

Any point in the right direction would be great. I've been watching videos and reading tutorials on functions, it doesn't seem to cover the problem I'm having...

#include <iostream>
#include <string>


using namespace std;

//Function Protos
void keyError();
int userInput(int x);

//class library
class Title
{
    bool nSelect;
    int x;
public:
    void titleScreen()
    {
        while(nSelect)
        {
            cout << "Welcome to Biggs RPG!" << endl << "1. Play 2. Exit" << endl;
            userInput(x);
                if (userInput(1))
                    nSelect = 0;
                else if (userInput(2))
                {
                    cout << "Closing program..." <<endl;
                    nSelect = 0;
                }
                else
                    keyError();
         }
    }
};

int main()
{
Title displayTitle;
displayTitle.titleScreen();

cout << "Good work";
return 0;
}

void keyError()
{
cout << "Meow? Wrong input try again." << endl;
}   

int userInput(int x)
{
x = 0;
cin >> x;
return x;
}
taocp
  • 23,276
  • 10
  • 49
  • 62

3 Answers3

2

You should compare the return value of userInput with 1 or 2, like this:

int userInput(void);

//class library
class Title
{
    bool nSelect;
    int x;
public:
    void titleScreen()
    {
        nSelect = true;
        while(nSelect)
        {
            cout << "Welcome to Biggs RPG!" << endl << "1. Play 2. Exit" << endl;
            x = userInput();
            if (x == 1)
                nSelect = false;
            else if (x == 2)
            {
                cout << "Closing program..." <<endl;
                nSelect = false;
            }
            else
                keyError();
         }
    }
};

and define userInput as:

int userInput(void)
{
    int x = 0;
    cin >> x;
    return x;
}
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • It gave me this when I tried it like that. error C2660: 'userInput' : function does not take 0 arguments – Token coding newbie Jun 01 '13 at 02:47
  • Did you also modified the declaration of "userInput" in the beginning of the program? `int userInput(void); `The declaration and definition should always use the same type of argument. – Yu Hao Jun 01 '13 at 02:55
  • It compiled but there is still logic errors. It's still taking the number and doing nothing with it. Thanks so much, I didn't get the (void) part, in the function or knew I could declare a variable with the function. – Token coding newbie Jun 01 '13 at 11:49
  • @user2442335 I just noticed that nSelect was defined as a `bool` type, but was assigned to 0. This is a bad style, it should be assigned to `ture` or `false`. And, since you didn't provide an explicit constructor, nSelect will be initialized to be `false`. – Yu Hao Jun 01 '13 at 12:00
2

There are numerous stylistic and technical problems. Try learning from resources recommended in The Definitive C++ Book Guide and List.

Here is a start…

#include <iostream>
#include <string>

// "using namespace std;" is poor practice. Better to write out std::

/*  Unless you will have two title screens at the same time,
    this should probably be a namespace, not a "singleton" class. */
namespace Title
{
    int nSelect;

    void titleScreen()
    {
        do {
            // prompt for input
            std::cout << "Welcome to Biggs RPG!\n" "1. Play 2. Exit\n";

            // get ready to accept input, even if there was an error before
            if ( ! std::cin ) {
                std::cin.clear(); // tell iostream we're recovering from an error
                std::cin.ignore( 1000, '\n' ); // ignore error-causing input
            }
            // repeat if invalid input
         } while( ! std::cin >> nSelect || ! handleInput( nSelect ) );

The difference is that you want to ask for input, then handle it. The code you posted asks for input again each time it checks what the input was.

This is a do … while loop, so it executes at least once and then repeats as long as the condition at the end is true. If the user gives an invalid input, then ! std::cin evaluates to true. Then the policy of C++ is to stop returning any input until you call std::cin.clear(), which signals that you are going to try again. ignore then gets rid of the invalid input. Then ! std::cin >> nSelect tries to read a number, and if that operation is successful, call handleInput (which you must write) which should return false if the input was invalid. So if reading a number fails, or the wrong number was entered, the loop goes again.

Community
  • 1
  • 1
Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • Okay looks like I need to study a bit more. It was my first attempt at creating a piece of something I might be able to use or modify later. What you posted above went over my head a little bit > – Token coding newbie Jun 01 '13 at 02:46
  • @user2442335 What part is over your head? I can clarify something. The code is just a rewrite of your prompt-for-input loop. – Potatoswatter Jun 01 '13 at 04:25
  • I haven't gone over namespaces yet, I heard briefly about singleton but I didn't get the scope of the context. I think it was just too advanced concept I couldn't visualize due to lack of experience. – Token coding newbie Jun 01 '13 at 11:46
  • 'std::cin.clear(); } while( ! std::cin >> nSelect || ! handleInput( nSelect ) );' Is what I really didn't get. I do know what a while loop is though :P XD – Token coding newbie Jun 01 '13 at 11:47
  • @user2442335 OK, I added more. You can look at http://cppreference.com to get info about anything in `std::` that you see in an answer. – Potatoswatter Jun 01 '13 at 12:00
  • Ok cool. I didn't know you could use cin and stuff in conditions. ! std::cin >> nSelect This is saying if cin isn't nSelect? I just haven't seen cin used for anything else except simple things like asking it for numbers. I'll check that website out ASAP. Would up vote but it wouldn't let me :P – Token coding newbie Jun 01 '13 at 12:28
  • It means ask `cin` for a number, and then test for success or failure. (Remember that `cin >> x` returns `cin`. And `! cin` is `true` if there was a failure.) – Potatoswatter Jun 01 '13 at 14:37
0

I sense confusion about the difference between parameters and return values. When you define a function as

int userInput(int x) {
  ...

You pass a value to the function (x) and return a value with the return statement. In your case you don't need to pass a parameter to your function; you need to return a value. You access this value by assigning it to another variable:

theResult = userInput(123);

But it doesn't matter what value you pass to the function; you might as well use

int userInput(void) {
  ...

In which case you can use

theResult = userInput();

Now just to confuse you, it is possible to pass the address of a variable as a parameter to a function. You can use that either to access data (usually a "larger" block of data like an array or struct) but it can also be used to provide a place where a return value is stored. Thus

void squareMe(int *x){
    *x*=*x;
}

Would return the square of the number pointed to in that location. You could then do

int x=4;
squareMe(&x);
cout << x;

Would print out 16 (!). This is because the function looks at the contents of the address (&x is the address of the variable x), and multiplies it by itself in- place.

I hope this explanation helps.

Floris
  • 45,857
  • 6
  • 70
  • 122
  • It seems like changing it to a (void) still has the issue of 1 or 2 not being accepted. I never knew a title screen was going to be such a difficult first task! – Token coding newbie Jun 01 '13 at 11:55