Advertisement

C++ Workshop - Looping & Switch Statements (Ch. 7)

Started by July 10, 2006 11:33 AM
48 comments, last by Dbproguy 16 years, 9 months ago
JOBe,

If you use cin's override of the >> operator, you will only be able to get access to one character at a time. However, cin has other methods, namely getline().

istrea::getline is used as follows:

#include <iostream>using namespace std;int main( ) {   char buffer[3];   cin.getline( buffer, 2 );   cout << buffer << endl;}


The above creates a buffer 3 characters long. (2 for the characters, 1 for a terminating null character).

Then cin.getline requests up to 2 character from the console and stores it in buffer.

Then you can use buffer[0] to check the first character, and buffer[1] to check the second character. You can also use strlen(buffer) to determine the number of characters in buffer.

So you know, I viewed that problem as more extra credit than anything. But it was one of the cooler things we did, due to being able to see color changes, etc...

As for enums, in C++ enums are just a way to define symbolic constants for literal constants. Their use is primarily to make code more readable, as you can do a comparison against the enum values, and you can assign the enum values rather than littering a program with literal constants (aka. magic numbers).

In other languages, where enums are classes, they have more uses, such as providing type safety and bounds checking against valid values.

Hope that answers your questions. Cheers!
Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
I think this is where Zahlman would say "STOP"! And tell you to use std::getline instead. But, eh, I still don't know the difference between the two except that on VC6 cin.getline() was broken.

Beginner in Game Development?  Read here. And read here.

 

Advertisement
cin.getline only allows you to use char arrays (and by extension, char pointers) while std::getline allows you to use std::string. Zahlman wouldn't care about using cin.getline so much as not using std::string.

As it stands, if you use a char array of size 3, then you open yourself for a world of hurt if the user enters in something like "hello world!". This could do anything from Nothing to Crash The Computer to Kill Your Family. The third option isn't likely, but in this Topsy-Turvy world we live in, who can say?

Basically, you have what is known as a Buffer Overflow. A very large number of security problems with software are a result of this. Using std::string makes it, if not impossible, at least much, much harder to fall pray to this security vulnerability.



C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

I couldn't remember whether we'd started using std::string at this point in the workshop yet or not. So I decided to use cin::getline with a character array, but come to think of it, I dont think we had used arrays yet. /sigh

As well, I always put in more checks than I describe when showing someone a code snippet. I try not to be overly complex when demonstrating a concept.

However, in this case, the cin.getline method takes as its second parameter the maximum number of characters to accept from the standard input (including the null). Any other characters in the current stream are discarded. So this is actually NOT a buffer overflow, as nobodynews indicated. This is perfectly safe code.

However, in my example I should have used getline(buffer, 3). Using 2 only allows enough room for 1 character, plus the null.

Feel free to take my example (with 3 instead of 2) and enter it into any ANSI standard compiler, with the required namespaces, etc...and you'll see it works just fine, even if you type "Hello World" in the console window.

In response to Alpha, yes...I prefer to use std::string over char* or char[]. Actually, I prefer to use C# now to C++, but that's neither here nor there. =) I don't think I'll ever write a line of C++ code again if I can avoid it.

Cheers!

Jeromy Walsh
Sr. Tools & Engine Programmer | Software Engineer
Microsoft Windows Phone Team
Chronicles of Elyria (An In-development MMORPG)
GameDevelopedia.com - Blog & Tutorials
GDNet Mentoring: XNA Workshop | C# Workshop | C++ Workshop
"The question is not how far, the question is do you possess the constitution, the depth of faith, to go as far as is needed?" - Il Duche, Boondock Saints
Quote:
Original post by jwalsh
However, in this case, the cin.getline method takes as its second parameter the maximum number of characters to accept from the standard input (including the null). Any other characters in the current stream are discarded. So this is actually NOT a buffer overflow, as nobodynews indicated. This is perfectly safe code.


My bad, man! I should have taken a closer look at the snippet. You're absolutely right, you didn't have an overflow.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

Quote:
Original post by jwalsh
#include <iostream>using namespace std;int main( ) {   char buffer[3];   cin.getline( buffer, 2 );   cout << buffer << endl;}





Thank you for the explanation jwalsh, however, using cin.getline(buffer, 2) caused me to only have one character being read, changing this to three made it work.

My first try of a good function for this is:
int Menu::CharToInt(char chColor[3]){	int iColor = 0;	std::cin.getline(chColor, 3);		const int MAXLETTERS = strlen(chColor);	for(int i = 0; i < MAXLETTERS; i++)	{		if (isalpha(chColor))		{			if (chColor == 'Q' || chColor == 'q')			{				return iColor = 16;			}			else			{				return iColor = 99;			}		}		else		{		        iColor = atoi (chColor);		}	}	return iColor; }


The only thing that happens though as nobodynews said, when I enter 145 for instance, it will cut off the first two characters and change them into the appropriate integer. But, after coming back to the function, there is still input in cin.getline() and it goes on without allowing me to give any other input myself.

Isn't this also buffer overflow? How can I stop this from happening?

[Edited by - J0Be on June 1, 2007 2:33:38 PM]
Advertisement
Well, tried it out, I don't need the for-loop, so I'll remove it from the function.

Going to continue tomorrow on improving my class in Exercise 2 and will probably have it done by the end of this week-end..... hopefully [smile]
Well, finished the Exercise 2 again, so, if any of you gentlemen could have a look at it and tell me where I could have improved it, I would be very much obliged.

Thank you.
Wow I guess this workshop has been dead for a while though I'm glad all the chapters have a thread. Anyways I went ahead and did chapter 6 then 7 (I'll do 11 in order :P)

Chapter 7 was I guess just the basic loops, nothing I didn't know. I went through chapter 6 a little too to make sure I had a good grip on what all that was but I am pretty sure I have got it nailed now.

Have fun,
Marcus/Dbproguy
--Dbproguy - My Blog - Tips, Opinions and Reviews about C++, Video Games, and Life

This topic is closed to new replies.

Advertisement