Jump to content
  • Advertisement
Sign in to follow this  
arithma

std::cin Peculiar Behavior

This topic is 4321 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I wrote these pieces of code into a console program in VC++2005:
char* getStrInput()
{
	char* result = NULL;
	char buffer[80];
	cin.getline( buffer, 80 );
	result = new char[strlen(buffer)+1];
	strcpy(result, buffer);
	return result;
}

void getRecordDesc( Record* record )
{
	cout << "First name: ";
	record->first = getStrInput();
	cout << "Last name:  ";
	record->last = getStrInput();
	cout << "Title:      ";
	record->title = getStrInput();

	cout << "Salary:     ";
	cin >> record->salary;
}

The strange thing is that if I don't precede a getRecordDesc() call with a cin.get(), the following is displayed:
First name: Last name:  
cursor here-------------^
The code here that actually (practically) executes before the getRecordDesc() is a single cin >> (char)somevariable... PS: this is part of a homework, yes... However we are learning about dynamic memory allocation and linked lists, so it is not relevant to what am asking about. Please help

Share this post


Link to post
Share on other sites
Advertisement
I'd say it has to do with those char*'s. Some string that's not null-terminated or such so the cout function continues writing what's next in memory untill it encounters a 0 character. Pointers can be a source of problems so use them with care. In this case, the C++ styled approach would be to use a std::string instead (char pointers are sometimes referred to as C-styled strings).

In fact, I just dealt with an almost identical situation. The old image loading code I wrote for my game used char*'s. When I adapted to a new folder structure, suddenly the game would only load the first 2 or 3 images... using strings solved the problem.

Share this post


Link to post
Share on other sites
What a horrible way to learn about dynamic memory allocation. Also, questions like this really belong in For Beginners.

Anyway.

Operations on streams have no concept of "real time". When you read from cin, the characters you get are any characters that haven't already been read. If everything that the user has input has already been processed, then the program will wait (the read call will "block") until there is more data available.

In addition, the console input is line-buffered, which means that data only "becomes available" a line at a time.

In your case, what is likely happening is that you first perform some kind of read which leaves a newline ('\n') behind (since every time the user inputs a line, there is a newline character at the end of that line). Then, when getRecordDesc() is called, it outputs the prompt, and calls getStrInput(). getStrInput() in turn calls cin.getline(), and since there *is* a line of text available (that is to say, there is a '\n' in the not-yet-processed queue, so there is a line which consists of all the characters ahead of that - all 0 of them - plus the newline itself), that (empty) line is read in as the "first line". Then the next prompt is displayed right away, on the same line (because nothing happened which would cause the terminal to skip to the next line).

Possible solutions:

- Always grab input a line at a time, and "re-parse" it with std::stringstream objects.

- Skip any unprocessed stuff with cin.ignore(), cin.sync() etc. Look up the documentation for this stuff; it's important to understand what's going on.

Share this post


Link to post
Share on other sites
The problem was solved like this:

// PRE
char choice;
cin >> choice; // get a single character
while( cin.peek() != '\n' )
cin.get();
cin.get(); // get new-line character



Is there anything else to know

-------
This is not the way we're learning about linked-lists. It is only a part of a bigger program that I'm writing for the assignment. The record is the node; not that we are learning these concepts using characters (yuck!)

Share this post


Link to post
Share on other sites
In that case, why not use std::string to represent text? :P

(You can read into a std::string by using the free function std::getline : e.g. std::getline(cin, mystring); )

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!