In article <11*********************@v45g2000cwv.googlegroups. com>,
pa********@gmail.com says...
Hey John!,
your kindness will be remembered!
Actually, I need one header file (protein.h) and one code file
(protein.c). Then I need to define two operators or functions.
-one that will read a file such as the one below and extract the
values for protName_, protFamily_, molWeight_
-and another one that will ask for those above values to be entered
and writes them into a file with the following format:
<Protein>
<Name>...</Name>
<Family>...</Family>
<Weight>...<Weight>
</Protein>
This isn't quite what you asked for, but it's reasonably close.
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <limits>
// The name we'll use for each record.
char record_name[] = "protein";
// This defines the names of the fields we read/store/display. For most
// practical purposes, the remainder of the program has no knowledge of
// anything related to proteins, what we store about them, etc.
char const *field_names[] = {"Name", "Family", "Weight"};
// There are better ways to do this, but this works for our purposes.
#define elements(array) (sizeof(array)/sizeof(array[0]))
// The real heart of things: a field that can be read, written, entered
// or displayed. Reading and writing are for XML-format files. Enter and
// display are interactive.
// WARNING: field::read does NOT read most XML files -- it reads what
// field::write produces, but most other valid XML files will NOT be
// read correctly. field::write writes out all data verbatim, so entry
// of incorrect data (e.g. some punctuation marks) will produce invalid
// XML.
//
class field {
std::string name;
std::string value;
virtual std::istream &read(std::istream &is) {
std::string temp;
std::getline(is, temp);
int start_name = temp.find_first_of("<")+1;
int end_name = temp.find_first_of(">");
int start_value=end_name+1;
int end_value=temp.find_first_of("<", start_value);
name = std::string(temp, start_name, end_name-start_name);
value = std::string(temp, start_value, end_value-start_value);
return is;
}
virtual std::ostream &write(std::ostream &os) const {
os << "\t<" << name << ">";
os << value;
os << "</" << name << ">\n";
return os;
}
public:
field(std::string const &s) : name(s) {}
field() { }
void get_interactive(std::ostream &os, std::istream &is) {
os << "Please enter " << name << ": ";
is >value;
}
std::ostream &show_interactive(std::ostream &os) const {
return os << name << ": " << value << "\n";
}
friend std::ostream &operator<<(std::ostream &os, field const &f) {
return f.write(os);
}
friend std::istream &operator>>(std::istream &is, field &f) {
return f.read(is);
}
virtual ~field() {}
};
// A collection of fields, the number and names of which are found in
// the field_names array. The current version has read and write that
// attempt to produce XML( albeit with no header), but read and write
// could be overridden to allow reading and writing other formats.
//
template<class field, char const *record_name>
class record {
std::vector<fieldfields;
virtual std::istream &read(std::istream &is) {
std::string temp;
std::getline(is, temp);
for (int i=0; i<fields.size(); i++)
is >fields[i];
std::getline(is, temp);
return is;
}
virtual std::ostream &write(std::ostream &os) const {
os << "<" << record_name << ">\n";
std::copy(fields.begin(), fields.end(),
std::ostream_iterator<field>(os));
os << "</" << record_name << ">\n";
return os;
}
public:
record() {
for (int i=0; i<elements(field_names); i++)
fields.push_back(field(field_names[i]));
}
std::ostream & show_interactive(std::ostream &os) const {
os << "\n";
for (int i=0; i<fields.size(); i++)
fields[i].show_interactive(os);
return os;
}
std::istream &get_interactive(std::ostream &os, std::istream &is) {
for (int i=0; i<fields.size(); i++)
fields[i].get_interactive(os, is);
return is;
}
friend std::ostream &operator<<(std::ostream &os, record const &r){
return r.write(os);
}
friend std::istream &operator>>(std::istream &is, record &r) {
return r.read(is);
}
virtual ~record() {}
};
typedef record<field, record_namerec;
I'm not sure if you really need the 'show' functions, but they were easy
and might be needed (I used them in testing, so I left them). The read
and write functions do XML (with considerable limitations, as noted in
the comments), and the enter allows you to enter new data interactively.
This code has been minimally tested, but has no error handling, so it's
not exactly a model of robust code.
Note that rec is a single record -- you'll typically want a vector<rec>
or something on that order.
--
Later,
Jerry.
The universe is a figment of its own imagination.