So for my comsci assignment, I need to read in this text file with a butt load of messages. Here is what the text file looks like:

1 R
Jemma
Harry
What were you thinking?
Harry,

You seriously need to stop claiming your paperclip orders under
the heading art supplies.

Jemma
EOF
2 R
Jemma
Jason
I really really want to talk to you about those expense claims!
Subject says it all...

Jemma
EOF

The first char is the message number, second is a status char meaning if it's read or unread, 2nd line is sender, 3rd line is recipient, 4th line is subject, and 5th line onward until "EOF" is the message body.

Now I've been able to read in all the lines perfectly into separate variables, with getline() and fstream, but now I figured I could store these messages as objects inside a vector if I create a class. This is my test code, everything compiles, except when I run it, it ends up storing the first message twice, instead of continuing the getline() from where it stopped before. Not sure how to get rid of this.

Here's my code:

#include <iostream>

#include <fstream>
#include <string>
#include <vector>

using namespace std;

// this is the class that I want to use to create instances of the messages
class Message
{
public:
	Message(); // default constructor
	void printMessage() const; // this prints it out so I can see if it works

private:
	int messageNum; 
	string status;
	string sender;
	string recipient;
	string subject;
	string messageBody;

};

Message::Message() // default constructor
{
	ifstream fin;	// declares fin to ifstream
	fin.open("mail.txt"); // opens the text file

	fin >> messageNum; // takes in the first char for message number
	getline(fin, status);  // takes in status R for read or N for new
	getline(fin, sender); // sender
	getline(fin, recipient); // recipient
	getline(fin, subject); // subject

	


	while (message != "EOF") // this will read in the message body until it sees EOF which means it is end of message body
	{
		messageBody.append(message); // puts the various lines in message body together
		if (messageBody != "")
		{
			messageBody.append("\n");		// adds the hard returns
		}
		getline(fin, message);		// gets the next line
	}
	

}

void Message::printMessage() const        // this member function just prints out all the info collected
{
	cout << messageNum << " " << status << endl << sender << endl << recipient << endl << subject << endl << messageBody;
}

int main()
{
	Message abc;   // creates instance
	Message cde;   // another instance


	vector<Message> systemMessages;  // creates vector
	systemMessages.push_back(abc);   // appends first instance
	systemMessages.push_back(cde);  // appends second instance
	systemMessages[0].printMessage();  // calls member function
	systemMessages[1].printMessage();  // calls member function for other
}

My output ends up being this :

1  R
Jemma
Harry
What were you thinking?
Harry,

You seriously need to stop claiming your paperclip orders under
the heading art supplies.

Jemma
1  R
Jemma
Harry
What were you thinking?
Harry,

You seriously need to stop claiming your paperclip orders under
the heading art supplies.

Jemma

I would appreciate the help. I'm a beginner in C++ :(
Thanks a lot, hope I made this clear and not too long to read...

First of all, you are not closing the 'fin' stream, but this is not the cause of your problems.

Let's check what is happening:
You create a Message object, which in its constructor opens a file and reads from it. After that the file is closed.
A second instance of Message is created, which opens the same text file again and reads from it.

The second instance will just start reading from the beginning of the file again.

** EDIT: Ok I just made a suggestion but when reading it again I realised it makes no sense... so here is a better version :P:

What you can do is promote the fin variable to a static member variable so that all of the objects you create share the same fin variable so that the second time you create an instance it will start reading where the first instance stopped.
Or, you can store a static member variable that defines how many lines have already been read, but I don't know if you can open a file and set the internal pointer at a certain 'offset', you'd have to read up on this.

So I suggest you read up on static member variables to see how you can use them for your problem.

Hmmm, how come when I try to put the Class definitions in a function, it causes an error? Are all classes supposed to be defined globallly?

What exactly are you doing, and what is the error?
Try to give information like that from the start, it will make it much easier for others to understand what you mean, and it avoids giving a solution that has nothing to do with what you are trying to do.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.