Jason Heyes said:
Does this function need to call eof after the while-loop to be correct?
bool read_file(std::string name, std::string &s)
{
std::ifstream in(name.c_str());
if (!in.is_open())
return false;
char c;
std::string str;
while (in.get(c))
str += c;
if (!in.eof())
return false;
s = str;
return true;
}
Thanks.
Why not extract the file's contents into a container of strings? If you make
the container a member of a class, read_file() and a write_file() could be
member functions of that class with access to the encapsulated container.
There are a number of other ways this could be done. You might overload the
write() member function so it takes a reference to another string container
to write to file, you might choose to use the same filestream to read /
write, etc.
// FileParser.cpp
//
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
#include <stdexcept>
class FileParser
{
// members
const std::string m_filename_;
std::string m_buffer;
std::ifstream m_ifs;
std:
fstream m_ofs;
std::vector<std::string> m_vs;
public:
// ctor
FileParser(std::string s)
: m_filename_(s), m_buffer(), m_ifs(), m_ofs(), m_vs() { }
~FileParser() { }
// read() member function
void read() throw(std::exception)
{
m_ifs.open(m_filename_.c_str(), std::ios::in);
if (!m_ifs)
{
throw std::exception("error opening file for read().\n");
}
while (std::getline(m_ifs, m_buffer))
{
m_vs.push_back(m_buffer);
}
if (!m_ifs.eof()) // if reason of termination != eof
{
throw std::exception("error while parsing file.\n");
}
}
// write(...) member function
void write() throw(std::exception)
{
m_ofs.open(m_filename_.c_str());
if (!m_ofs)
{
throw std::exception("error opening file for write().\n");
}
// copy algorithm with ostream_iterator
std::copy( m_vs.begin(),
m_vs.end(),
std:
stream_iterator<std::string>(m_ofs, "\n") );
}
// load(...) member function
void load(std::vector<std::string>& r_vs)
{
m_vs.clear();
std::copy(r_vs.begin(), r_vs.end(), std::back_inserter(m_vs));
}
// display() member function
void display() const
{
std::cout << "\n--- FileParse::display() ---\n\n";
std::copy( m_vs.begin(),
m_vs.end(),
std:
stream_iterator<std::string>(std::cout,
"\n") );
}
}; // class FileParser
int main()
{
std::vector<std::string> vstrings;
vstrings.push_back("string 0");
vstrings.push_back("string 1");
vstrings.push_back("string 2");
vstrings.push_back("string 3");
vstrings.push_back("string 4");
// FileParser object
FileParser fileparser("file.dat");
fileparser.load(vstrings);
fileparser.display();
try
{
fileparser.write();
fileparser.read();
fileparser.display();
}
catch (const std::exception& e)
{
std::cout << "Error:\n";
std::cout << e.what();
}
return 0;
} // main()
/* file.dat
--- FileParse::display() ---
string 0
string 1
string 2
string 3
string 4
*/