Jump to content

  • Log In with Google      Sign In   
  • Create Account


[C++]problem with getline


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 sheep19   Members   -  Reputation: 388

Like
0Likes
Like

Posted 27 April 2011 - 01:15 PM

Hi. I have a file with highscores which I want to open, read and close.

The file inside has 30 rows of data which are
name[0]
score[0]
date[0]
.
.
.
name[9]
score[9]
date[9]

So I am gathering input. I get a string (for the name), then an integer (score) and then another string (the date).
The date and maybe the name will have spaces inside them, so I want to use getline instead of the >> operator to read the strings correctly.

This is my code:
while( !in.eof() )
		{
			//in >> highscores.names[i]; // read name
			getline(in, highscores.names[i], '\n');
			++counter;

			in >> highscores.scores[i]; // read score
			++counter;

			in >> highscores.dates[i]; // read date
			++counter;

			++i;
		}

This is just a test, to read the name using getline and the other two with the >> operator.
However, if I use getline, my program crashes! If I don't, it works (it works because the strings that I have inside the savefile haven't got spaces between them)

Why does it crash when I use getline? (The file opens correctly).

Sponsor:

#2 yewbie   GDNet+   -  Reputation: 665

Like
0Likes
Like

Posted 27 April 2011 - 01:32 PM

Why does it crash when I use getline? (The file opens correctly).


You should check the value on i when the program crashes, I would suspect getline is not reading your file like you think it is.
I would assume your writing data outside of your struct

#3 greggles   Members   -  Reputation: 347

Like
1Likes
Like

Posted 27 April 2011 - 01:53 PM

The extraction (>>) operator will not read in the \n after date. So when getline is called, it reads in an empty string.

An example (with endlines shown as \n instead of whitespace):


John \n
300 \n
3/3/2011 \n
Ed \n
300 \n
3/4/2011 \n

Your code will read in the first set of data correctly, but this is what the file looks like after it is done:

\n
Ed \n
300 \n
3/4/2011 \n

So the next name will be "", the next score will be "Ed", and the next date will be "300". Obviously this isn't correct and will cause an error.

#4 sheep19   Members   -  Reputation: 388

Like
0Likes
Like

Posted 27 April 2011 - 04:59 PM

The extraction (>>) operator will not read in the \n after date. So when getline is called, it reads in an empty string.

An example (with endlines shown as \n instead of whitespace):


John \n
300 \n
3/3/2011 \n
Ed \n
300 \n
3/4/2011 \n

Your code will read in the first set of data correctly, but this is what the file looks like after it is done:

\n
Ed \n
300 \n
3/4/2011 \n

So the next name will be "", the next score will be "Ed", and the next date will be "300". Obviously this isn't correct and will cause an error.


Thank you, I have fixed it now =]

I put a dummy string which I read after operator >> .

#5 rip-off   Moderators   -  Reputation: 7641

Like
1Likes
Like

Posted 28 April 2011 - 03:27 AM

Reading an dummy string is a brittle approach.

A different way of handling this is to not mix std::getline and operator>>. Use getline() for everything, then re-parse the data in memory as a non-string type using std::stringstream:
#include <sstream>
#include <iomanip>

// Helper function
bool convert_to(const std::string &text, int &number)
{
    std::stringstream stream(text);
    return (stream >> number && stream >> std::ws && stream.eof()); // Is the entire string a valid integer (barring whitespace)?
}

// Elsewhere...
std::string name, score, date;
while(std::getline(in, name) && std::getline(in, score) && std::getline(in, date))
{
    HighScore &highScore = highscores[i];
    
    highscore.name = name;
    ++counter;

    if(!convert_to(score, highscore.score))
    {
        // handle error
    }
    ++counter;

    if(!convert_to(date, highscore.date)) 
    {
        // handle error
    }
    ++counter;

    ++i;
}         
Also note how this code has a lot more error handling than your original attempt. This is important whenever you are dealing with external information that could be easily corrupted.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS