 |
BOOK: Professional C++, 2nd Edition  | This is the forum to discuss the Wrox book Professional C++, 2nd Edition by Marc Gregoire, Nicholas A. Solter, Scott J. Kleper ; ISBN: 978-1-1181-6995-7 |
|
Welcome to the p2p.wrox.com Forums.
You are currently viewing the BOOK: Professional C++, 2nd Edition section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|

May 14th, 2016, 10:49 PM
|
Authorized User
|
|
Join Date: Nov 2014
Posts: 91
Thanks: 2
Thanked 1 Time in 1 Post
|
|
Chapter 15 Demystifying C++ I/O
Marc,
Storing a class object in a container is temporary, and all data is lost when the program terminates. How do you store a class object data in a file and read that data afterwards? Say, the data members are two strings (e.g., mFirstName and mLastName) and a character (e.g. mMiddleInitial).
|

May 15th, 2016, 07:01 AM
|
Wrox Author
|
|
Join Date: Mar 2011
Posts: 49
Thanks: 0
Thanked 4 Times in 4 Posts
|
|
On page 559, there is a section called "Input and Output with Objects" that explains how to add support for operator<< and >> to your own objects.
With these you can then stream your objects to for example a file stream discussed elsewhere in the same chapter.
|

May 15th, 2016, 03:43 PM
|
Authorized User
|
|
Join Date: Nov 2014
Posts: 91
Thanks: 2
Thanked 1 Time in 1 Post
|
|
Chapter 15 Demystifying C++ I/O
Sorry Marc, but I was not able to put the pieces together. I need to see an explicit example.
I modified the void output() method to write to a file. It is shown in the code as boldfaced.
Now, how do you read the Muffin.txt file?
Code:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
class Muffin
{
public:
string getDescription() const;
void setDescription(const string& inDesc);
int getSize() const;
void setSize(int inSize);
bool getHasChocolateChips() const;
void setHasChocolateChips(bool inChips);
void output();
protected:
string mDesc;
int mSize;
bool mHasChocolateChips;
};
string Muffin::getDescription() const { return mDesc; }
void Muffin::setDescription(const string& inDesc) { mDesc = inDesc; }
int Muffin::getSize() const { return mSize; }
void Muffin::setSize(int inSize) { mSize = inSize; }
bool Muffin::getHasChocolateChips() const { return mHasChocolateChips; }
void Muffin::setHasChocolateChips(bool inChips) { mHasChocolateChips = inChips; }
void Muffin::output()
{
ofstream outFile("Muffin.txt", ios::out | ios::app);
if(!outFile.is_open()) {
cerr << "File could not open!";
return;
}
outFile << getDescription().c_str() << getSize() << getHasChocolateChips() << '\n';
outFile.clear();
outFile.close();
}
Muffin createMuffin(istringstream& inStream);
int main()
{
cout << "First, let's create a muffin in code and output it." << endl;
Muffin m;
m.setDescription("Giant_Blueberry_Muffin");
m.setSize(42);
m.setHasChocolateChips(false);
m.output();
cout << "Now we'll create a muffin from a string stream" << endl;
istringstream instream("My_Muffin 2 true");
Muffin m2 = createMuffin(instream);
m2.output();
return 0;
}
Muffin createMuffin(istringstream& inStream)
{
Muffin muffin;
// Assume data is properly formatted:
// Description size chips
string description;
int size;
bool hasChips;
// Read all three values. Note that chips is represented
// by the strings "true" and "false"
inStream >> description >> size >> boolalpha >> hasChips;
muffin.setSize(size);
muffin.setDescription(description);
muffin.setHasChocolateChips(hasChips);
return muffin;
}
The output in the Muffin.txt file was as follows:
Code:
Giant_Blueberry_Muffin420
My_Muffin21
Last edited by phztfte1; May 15th, 2016 at 06:48 PM..
Reason: Correct editorial error and added check if file opened.
|

May 16th, 2016, 04:08 AM
|
Wrox Author
|
|
Join Date: Mar 2011
Posts: 49
Thanks: 0
Thanked 4 Times in 4 Posts
|
|
You'll have to format the data in such a way that you can read it back.
If you look at the createMuffin() method, you see that it is able to parse/read muffins formatted as follows:
Muffin_Name Size Chips
So, name followed by a space, followed by the size, a space and true or false for the chocolade chips.
If you want to use createMuffin to read data from a file, then you should modify output() to write it in that format. So, for example:
Code:
void Muffin::output()
{
ofstream outFile("Muffin.txt", ios::out | ios::app);
if(!outFile.is_open()) {
cerr << "File could not open!";
return;
}
outFile << getDescription() << " " << getSize() << " " << boolalpha << getHasChocolateChips() << '\n';
}
Some notes:
* No need for the clear() or close(). The file is automatically closed.
* booalpha is used to write true/false instead of 1/0
* no need for the .c_str() when writing a std::string to a C++ stream.
* This obviously only works if there are no spaces in the name of the muffin. If you want to support spaces in the name, then you can take a look at the quoted manipulator. (see https://msdn.microsoft.com/en-us/library/dn986842.aspx)
|

May 18th, 2016, 11:30 PM
|
Authorized User
|
|
Join Date: Nov 2014
Posts: 91
Thanks: 2
Thanked 1 Time in 1 Post
|
|
Chapter 15 Demystifying C++ I/O
Hi Marc,
I revised the output() method as you suggested and added an input() method. The input() method does not work but at least, it is a start.
1. The input() method does not read the bool value for chips correctly. Instead of reading false, it shows true.
2. The exercise raises a question: how do you get to read the next record?
Code:
include <iostream>
#include <sstream>
#include <string>
#include <fstream>
using namespace std;
class Muffin
{
public:
string getDescription() const;
void setDescription(const string& inDesc);
int getSize() const;
void setSize(int inSize);
bool getHasChocolateChips() const;
void setHasChocolateChips(bool inChips);
void output();
void input();
protected:
string mDesc;
int mSize;
bool mHasChocolateChips;
};
string Muffin::getDescription() const { return mDesc; }
void Muffin::setDescription(const string& inDesc) { mDesc = inDesc; }
int Muffin::getSize() const { return mSize; }
void Muffin::setSize(int inSize) { mSize = inSize; }
bool Muffin::getHasChocolateChips() const { return mHasChocolateChips; }
void Muffin::setHasChocolateChips(bool inChips) { mHasChocolateChips = inChips; }
void Muffin::output()
{
printf("%s, Size is %d, %s\n", getDescription().c_str(), getSize(),
(getHasChocolateChips() ? "has chips" : "no chips"));
ofstream outFile("Muffin.txt", ios::out | ios::app);
if (!outFile) {
cerr << "File could not open!" << endl;
return;
}
outFile << getDescription() << '^' << getSize() << '^' << boolalpha << getHasChocolateChips() << '\n';
}
void Muffin::input()
{
string description;
int size;
bool chips;
ifstream inFile("Muffin.txt", ios::in);
if (!inFile) {
cerr << "File could not open!" << endl;
return;
}
getline(inFile, description, '^');
inFile >> size;
inFile >> chips;
cout << "inFile: " << description << " " << size << " " << boolalpha << chips << endl;
}
Muffin createMuffin(istringstream& inStream);
int main()
{
cout << "First, let's create a muffin in code and output it." << endl;
Muffin m;
m.setDescription("Giant Blueberry Muffin");
m.setSize(42);
m.setHasChocolateChips(false);
m.output();
cout << "Now we'll create a muffin from a string stream" << endl;
istringstream instream("My_Muffin 2 true");
Muffin m2 = createMuffin(instream);
m2.output();
Muffin muff;
muff.input();
return 0;
}
Muffin createMuffin(istringstream& inStream)
{
Muffin muffin;
// Assume data is properly formatted:
// Description size chips
string description;
int size;
bool hasChips;
// Read all three values. Note that chips is represented
// by the strings "true" and "false"
inStream >> description >> size >> boolalpha >> hasChips;
muffin.setSize(size);
muffin.setDescription(description);
muffin.setHasChocolateChips(hasChips);
return muffin;
}
Here are the contents of the text file.
Code:
Giant Blueberry Muffin^42^false
My_Muffin^2^true
|

May 19th, 2016, 02:00 PM
|
Wrox Author
|
|
Join Date: Mar 2011
Posts: 49
Thanks: 0
Thanked 4 Times in 4 Posts
|
|
One option is to write them as follows:
Code:
outFile << quoted(getDescription()) << ' ' << getSize() << ' ' << boolalpha << getHasChocolateChips() << '\n';
Note that I'm using the quoted() manipulator and replaced the ^ with spaces.
The following is then one way to read the data back:
Code:
while (!inFile.eof())
{
description = "";
inFile >> quoted(description);
if (description.empty())
{
break;
}
inFile >> size >> boolalpha >> chips;
cout << "inFile: " << description << " " << size << " " << boolalpha << chips << endl;
}
|

May 19th, 2016, 10:20 PM
|
Authorized User
|
|
Join Date: Nov 2014
Posts: 91
Thanks: 2
Thanked 1 Time in 1 Post
|
|
Chapter 15 Demystifying C++ I/O
Marc,
I did not use quoted because when I read the documentation it was for Visual Studio 2015 and new to C++14. There is a red squiggly line under quoted even though the header file <iomanip> was added. I use Visual Studio 2013 Professional which does not implement C++14.
So, how does one do it without quoted?
|

June 1st, 2016, 01:40 PM
|
Wrox Author
|
|
Join Date: Mar 2011
Posts: 49
Thanks: 0
Thanked 4 Times in 4 Posts
|
|
Just try to remove the quoted() then.
In that case of course, the name cannot contain spaces.
If you do want to support spaces, then you'll have to do some more parsing yourself, for example by quoting it yourself.
|

June 3rd, 2016, 09:58 AM
|
Authorized User
|
|
Join Date: Nov 2014
Posts: 91
Thanks: 2
Thanked 1 Time in 1 Post
|
|
Chapter 15 Demystifying C++ I/O
Say my data members were an int and a double. When writing to a text file, are ithe int and double converted to text?
|

June 4th, 2016, 09:35 AM
|
Wrox Author
|
|
Join Date: Mar 2011
Posts: 49
Thanks: 0
Thanked 4 Times in 4 Posts
|
|
If you write them with operator <<, then yes, they are converted to text.
|
Similar Threads
|
Thread |
Thread Starter |
Forum |
Replies |
Last Post |
More Help with chapter 15 |
happyandstable |
BOOK: Beginning ASP.NET 4 : in C# and VB |
3 |
March 12th, 2012 03:19 AM |
chapter 15 help |
kyledonmoyer |
BOOK: Beginning PHP5, Apache, and MySQL Web Development ISBN: 978-0-7645-7966-0 |
2 |
June 30th, 2007 08:06 AM |
Chapter 15 |
rrlevron |
BOOK: Beginning ASP 3.0 |
0 |
November 17th, 2005 03:38 PM |
chapter 15 |
manal_sag |
BOOK: Beginning ASP 3.0 |
0 |
April 22nd, 2005 02:23 PM |
Chapter 15 |
moggie |
BOOK: Beginning ASP 3.0 |
2 |
October 19th, 2004 01:30 PM |
|
 |