Newbie needs some help

Anable

Newbie
Joined
Nov 21, 2003
Messages
270
Reaction score
0
I have a magic 8 ball program that I've been working on and the whole thing works fine except that when it asks if you want to go again, it assumes your input and goes directly to your answer. Now I think this is happening because the array that the answer is stored in already has a value associated with it and doesn't bother asking you for new information to put in it. How do I fix this? Is there a way to clear the information in an array after you're done with it or am I approaching it from completely the wrong angle? Here's the code if it helps out any:
Code:
#include <iostream.h>
#include <stdlib.h>
#include <time.h>

#define HIGH 10
#define LOW 1

void meaningless();
unsigned long timeseed();
void output(int number);
void again();

int main()
{
	unsigned long result;

	cout << endl << endl << "Magic 8-ball as performed by anable" << endl << endl << endl;
	meaningless();
	result = timeseed();
	output(result);
	again();
	cout << endl;

	return 0;
};

void meaningless() //This eats the characters for the question and does nothing with it
{
	char question[200];
	cout << "What is your question? ";
	cin.getline(question,200);
};

unsigned long timeseed()            //This creates a unique seed for rand 
{
	int number;
	time_t seconds;                 //Creates time variable
	time(&seconds);                 //Takes system time and puts it into variable "seconds"
	srand((unsigned int) seconds);  //Dunno what it does but I think I need it
	number = rand() % (HIGH - LOW + 1) + LOW; //Ensures random number is between 1 and 10
	return number;
};

void output(int number)
{
	switch (number)
	{
	case 1:
		cout << "Signs point to yes." << endl;
		break;
	case 2:
		cout << "Without a doubt." << endl;
		break;
	case 3:
		cout << "My sources say no." << endl;
		break;
	case 4:
		cout << "Outlook not so good." << endl;
		break;
	case 5:
		cout << "Better not tell you now." << endl;
		break;
	case 6:
		cout << "Ask again later." << endl;
		break;
	case 7:
		cout << "Don't count on it." << endl;
		break;
	case 8:
		cout << "Who knows?" << endl;
		break;
	case 9:
		cout << "Forget about it." << endl;
		break;
	case 10:
		cout << "Probably." << endl;
		break;
	default:
		cout << "Ah..you shouldn't be seeing this..." << endl;
	}
};

void again()           //Checks to see if you want to run the program again.
{
	char buffer;
	
	cout << "Would you like to ask another question? (y/n) ";
	cin  >> buffer;
	if (buffer == 'y')
	{
		main();
	}
	else
	{
		exit(0);
	}
}

Thanks for the help!
 
It probably has to do with the fact that you calling main() again... Try a while loop, something like this:
Code:
do 
{
	cout << endl << endl << "Magic 8-ball as performed by anable" << endl << endl << endl;
	meaningless();
	result = timeseed();
	output(result);

}while(Again());  //Again() returns 1 if they want to do it again, otherwise 0


//.....later on down the line with the Again() function
int Again()
{
char a;
cout<<"would  you like to do it again?";
cin>>a;
if(a == 'y')
return 1;

return 0;
}

Also, the meaningless(...) function really is meaningless. The array you store is local to the function, which means that
A) only your function can access it and
B) it gets destroyed when the function returns

Just get ask the question and put it into a char, and don't even bother doing anything with it. e.g.
Code:
char a;
cout<<"what is dinah question?";
cin>>a;
return;

you want to get away from calling main(). Thats a bad habit. The only thing calling main should be the OS. (operating system). It's syntatically correct, and it's called recursion, and you can do it with functions. just don't do it with main.
 
Ya, I didn't think that calling on main() was a good idea but because of my limited knowledge it was the best I could come up with. I'll give the do while loop a try and see what I can get done. Thanks for the help.
 
Ok, I have revision 2 done but I'm still having the same problem. Here's my new code:

Code:
#include <iostream.h>
#include <stdlib.h>
#include <time.h>

#define HIGH 10
#define LOW 1

void intro();
void meaningless();
unsigned long timeseed();
void output(int number);
char more();

/////////////////////////////////////////////////////////////////////

int main()
{
	unsigned long result;
	char again;

	intro();
	do
	{
	meaningless();
	result = timeseed();
	output(result);
	again = more();
	}while (again == 'y');

	return 0;
};

/////////////////////////////////////////////////////////////////////

void intro() //Runs once and introduces the program
{
	cout << endl << endl << "Magic 8-ball as performed by anable" << endl << endl << endl;
};

/////////////////////////////////////////////////////////////////////

void meaningless() //This eats the characters for the question and does nothing with it
{
	char question[200];
	cout << "What is your question? ";
	cin.getline(question,200);
};

/////////////////////////////////////////////////////////////////////

unsigned long timeseed()            //This creates a unique seed for rand 
{
	int number;
	time_t seconds;                 //Creates time variable
	time(&seconds);                 //Takes system time and puts it into variable "seconds"
	srand((unsigned int) seconds);  //Dunno what it does but I think I need it
	number = rand() % (HIGH - LOW + 1) + LOW; //Ensures random number is between 1 and 10
	return number;
};

/////////////////////////////////////////////////////////////////////

void output(int number)             //Gives response based on random number given by timeseed()
{
	switch (number)
	{
	case 1:
		cout << "Signs point to yes." << endl;
		break;
	case 2:
		cout << "Without a doubt." << endl;
		break;
	case 3:
		cout << "My sources say no." << endl;
		break;
	case 4:
		cout << "Outlook not so good." << endl;
		break;
	case 5:
		cout << "Better not tell you now." << endl;
		break;
	case 6:
		cout << "Ask again later." << endl;
		break;
	case 7:
		cout << "Don't count on it." << endl;
		break;
	case 8:
		cout << "Who knows?" << endl;
		break;
	case 9:
		cout << "Forget about it." << endl;
		break;
	case 10:
		cout << "Probably." << endl;
		break;
	default:
		cout << "Ah..you shouldn't be seeing this..." << endl;
	}
};

/////////////////////////////////////////////////////////////////////

char more()                                 //Returns answer to loop question
{
	char answer;

	cout << "Would you like to ask another question? (y/n): ";
	cin  >> answer;
	return answer;
};

The problem is the same as before, after you say y for yes, the loop runs but it assumes your question and doesn't give you an opportunity to respond. As an added note, I can't do just the single char like you said EvNTHriZen because the excess characters spill over and get put into the (y/n) cin and cause it to exit the program. Thanks for helping me with the problem I was having calling main() though. Any more ideas on how to get around this?
 
OK dude... i looked over your code, and, to be honest with you, i can't figure out what is wrong other then you are using C's console functions. I am not sure if you want to program in C or C++, but i got the code to work by replacing some code:
Code:
//in the includes i got rid of#include <iostream.h> and added
#include <iostream>
//i also added 
#include <string>
using namespace std;

//the meaningless function i changed to:
void meaningless()
{
string a;
cout<<"What is your question? ";
cin>>a;
}

and it worked the way it was supposed to. My knowledge of C strings and C console fucntions is limited... i can use them, but if something comes up like this i don't know why it was causing a run over...
 
Pendragon - If you'd show me how to do it, I'd love to. It's not something I know how to do on my own.

EvNTHriZen - I made the changes you put in there but it still has a run over problem. Perhaps it has something to do with my complier? I'm not to straight on how different complier interpret code so that could be completely off base. It's the only thing I can think of though since I put in the code the way you have it exactly and I still have the problem. I'm using Visual C++.
 
Her is my code listing which works in my compiler, which is VC++6.0:
Code:
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string>
using namespace std;

#define HIGH 10
#define LOW 1

void intro();
void meaningless();
unsigned long timeseed();
void output(int number);
char more();

/////////////////////////////////////////////////////////////////////

int main()
{
	unsigned long result;
	char again;

	intro();
	do
	{
	meaningless();
	result = timeseed();
	output(result);
	again = more();
	}while (again == 'y');

	return 0;
};

/////////////////////////////////////////////////////////////////////

void intro() //Runs once and introduces the program
{
	cout << endl << endl << "Magic 8-ball as performed by anable" << endl << endl << endl;
};

/////////////////////////////////////////////////////////////////////

void meaningless() //This eats the characters for the question and does nothing with it
{
	string a;
	cout<<"WHAT is your question? ";
	cin>>a;
};

/////////////////////////////////////////////////////////////////////

unsigned long timeseed()            //This creates a unique seed for rand 
{
	int number;
	time_t seconds;                 //Creates time variable
	time(&seconds);                 //Takes system time and puts it into variable "seconds"
	srand((unsigned int) seconds);  //Dunno what it does but I think I need it
	number = rand() % (HIGH - LOW + 1) + LOW; //Ensures random number is between 1 and 10
	return number;
};

/////////////////////////////////////////////////////////////////////

void output(int number)             //Gives response based on random number given by timeseed()
{
	switch (number)
	{
	case 1:
		cout << "Signs point to yes." << endl;
		break;
	case 2:
		cout << "Without a doubt." << endl;
		break;
	case 3:
		cout << "My sources say no." << endl;
		break;
	case 4:
		cout << "Outlook not so good." << endl;
		break;
	case 5:
		cout << "Better not tell you now." << endl;
		break;
	case 6:
		cout << "Ask again later." << endl;
		break;
	case 7:
		cout << "Don't count on it." << endl;
		break;
	case 8:
		cout << "Who knows?" << endl;
		break;
	case 9:
		cout << "Forget about it." << endl;
		break;
	case 10:
		cout << "Probably." << endl;
		break;
	default:
		cout << "Ah..you shouldn't be seeing this..." << endl;
	}
};

/////////////////////////////////////////////////////////////////////

char more()                                 //Returns answer to loop question
{
	char answer=0;

	cout << "Would you like to ask another question? (y/n): ";
	cin  >> answer;
	return answer;
};
BTW.. if you are using VC++, go to Build->Rebuild All. This deletes any .obj files and anything else the linker might use, then starts over from scratch.
 
Wow, this is bizarre. I copy and paste that exact code and it has the over run problem. Doesn't even let me reply with y/n. And I'm using the exact same complier, VC++6.0. Stupid programing, maybe I shouldn't get into this field after all.
 
here is my output:
Code:
Magic 8-ball as performed by anable


WHAT is your question? aldkjfaldfjsl
Outlook not so good.
Would you like to ask another question? (y/n): y
WHAT is your question? lkasdjflaks
Probably.
Would you like to ask another question? (y/n): y
WHAT is your question? sajuewlncxwl
Probably.
Would you like to ask another question? (y/n): n
Press any key to continue

try a new project.
File->New...
Select the "Projects" tab
check "Win32 Console Application" and give it a name
choose "Empty Project" (the first radio button)
then
Project->"Add to Project"->New...
choose "source file" and give it a name.
copy the code, paste it in the source window, build and run it again.
View my signature.
Let me know how it comes out.

Dont' get discouraged. In fact, you should get used to it :) It's the name of the game. When you get better, you see common mistakes begining to happen, and you fix them quicky. Of course the flip side of that is as you get better your code becomes more complex, and the bugs become even more difficult to find. :)
If you think it goes away, read this thread:
Bugs
 
Anable said:
I have a magic 8 ball program that I've been working on and the whole thing works fine except that when it asks if you want to go again, it assumes your input and goes directly to your answer. Now I think this is happening because the array that the answer is stored in already has a value associated with it and doesn't bother asking you for new information to put in it. How do I fix this? Is there a way to clear the information in an array after you're done with it or am I approaching it from completely the wrong angle? Here's the code if it helps out any:
Code:
#include <iostream.h>
#include <stdlib.h>
#include <time.h>

#define HIGH 10
#define LOW 1

void meaningless();
unsigned long timeseed();
void output(int number);
void again();

int main()
{
	unsigned long result;

	cout << endl << endl << "Magic 8-ball as performed by anable" << endl << endl << endl;
	meaningless();
	result = timeseed();
	output(result);
	again();
	cout << endl;

	return 0;
};

void meaningless() //This eats the characters for the question and does nothing with it
{
	char question[200];
	cout << "What is your question? ";
	cin.getline(question,200);
};

unsigned long timeseed()            //This creates a unique seed for rand 
{
	int number;
	time_t seconds;                 //Creates time variable
	time(&seconds);                 //Takes system time and puts it into variable "seconds"
	srand((unsigned int) seconds);  //Dunno what it does but I think I need it
	number = rand() % (HIGH - LOW + 1) + LOW; //Ensures random number is between 1 and 10
	return number;
};

void output(int number)
{
	switch (number)
	{
	case 1:
		cout << "Signs point to yes." << endl;
		break;
	case 2:
		cout << "Without a doubt." << endl;
		break;
	case 3:
		cout << "My sources say no." << endl;
		break;
	case 4:
		cout << "Outlook not so good." << endl;
		break;
	case 5:
		cout << "Better not tell you now." << endl;
		break;
	case 6:
		cout << "Ask again later." << endl;
		break;
	case 7:
		cout << "Don't count on it." << endl;
		break;
	case 8:
		cout << "Who knows?" << endl;
		break;
	case 9:
		cout << "Forget about it." << endl;
		break;
	case 10:
		cout << "Probably." << endl;
		break;
	default:
		cout << "Ah..you shouldn't be seeing this..." << endl;
	}
};

void again()           //Checks to see if you want to run the program again.
{
	char buffer;
	
	cout << "Would you like to ask another question? (y/n) ";
	cin  >> buffer;
	if (buffer == 'y')
	{
		main();
	}
	else
	{
		exit(0);
	}
}

Thanks for the help!


I'm just going to ignore the rest of the thread and say replace all you cin's with cin.getlines even if it's just for one char. I'v had problems with mixing cin >> and cin.getline.
 
change
Code:
cin  >> buffer;

to

Code:
(cin  >> buffer).get();

The problem is that cin leaves the newline in the inputqueue so cin.getline() gets it and thinks you entered an empty string.
 
First off, I'd like to thank everyone that's tried to help me out so far. Now on to the updates:

mrchimp: I can't use cin.getline when returning the answer variable because then I can't match it against 'y' to determine if I need to do the loop again.

EvNTHriZen: Believe it or not, I opened up an entirely new workspace, created an entirely new cpp file, and complied it completely seperate from my old files; copying and pasting your code exactly from the forum, and I still have the same problem.

Bert: Amazing! It worked. I figured that the problem was something like that the whole time but I had no clue on how to fix it. To help me in the future, let me make sure I understand the syntax correctly. The only thing it's used for is to ensure that the newline input from hitting return doesn't get computed? Does it do anything else ever?
 
When I use getch(), it only waits for any input, not the return key, before continuing.
 
When you use cin>>buffer, it reads in buffer and returns the cin object, you can then just call the get() method of that object. All get() does is read a single character from the input stream. When you read in buffer it left the newline in the input queue and the cin.get() "catches" it.
You could've used
Code:
cin  >> buffer;
cin.get();

but
Code:
(cin  >> buffer).get();
is shorter.
 
Anable said:
First off, I'd like to thank everyone that's tried to help me out so far. Now on to the updates:

mrchimp: I can't use cin.getline when returning the answer variable because then I can't match it against 'y' to determine if I need to do the loop again.

Well 'Y' is a char and a string is an array of chars so buffer[1] == 'y' should work.

Bert couldn't you use "cin.get(char)" in a similiar way to how you use "cin.getline(buffer, length)"?
 
Yes, you can use cin.get(buffer,buffersize), just remember that it leaves the newline in the input queue,unlike cin.getline().
 
Back
Top