//
//
//
//
// Lab. Calcolo II - Esempio di codice
//
//
//
//
//
//
//
// Example code: STL-based sort.
#include
#include
#include
#include
#include
#include
#include
#include
#include
template class measurement;
template
std::ostream &operator<< (std::ostream &os, const measurement meas);
template
std::istream &operator>> (std::istream &is, measurement &meas);
template class measurement {
friend std::ostream &operator<< (std::ostream &os, const measurement meas);
friend std::istream &operator>> (std::istream &is, measurement &meas);
public:
typedef TNUM value_type;
// Creators
measurement(const TNUM& value, const std::string date,
const std::string observer) :
m_value(value), m_date(date), m_observer(observer) {}
measurement() {}
// Destructor
~measurement() {}
TNUM value() const { return m_value; } // Use as 'rvalue'
TNUM& value() { return m_value; } // Use as 'lvalue'
void value(const TNUM& new_value) { m_value = new_value; } // Value assignment
const std::string &get_date() const { return m_date; }
const std::string &get_observer() const { return m_observer; }
// Strictly speaking, we'd need operator< only, but this can
// be really confusing...
bool operator< (const measurement m) const { return m_value < m.value(); }
bool operator> (const measurement m) const { return m_value > m.value(); }
private:
TNUM m_value;
std::string m_date;
std::string m_observer;
};
template
std::ostream &operator<< (std::ostream &os, const measurement meas)
{
return os << meas.m_date << " - " << meas.m_observer
<< " - " << meas.m_value;
}
template
std::istream &operator>> (std::istream &is, measurement &meas)
{
bool input_done = false;
while(!input_done)
{
std::stringbuf rsbuf;
std::string line;
is.get(rsbuf);
line=rsbuf.str();
if (!line.empty())
{
is.clear(); // We may be at EOF after reading a valid record.
std::string::size_type pos_sep1 = line.find_first_of('-');
std::string::size_type pos_sep2 = line.find_last_of('-');
if (pos_sep1 == std::string::npos || pos_sep2 == std::string::npos)
continue; // Skip malformed lines
meas.m_date = line.substr(0,pos_sep1-1);
meas.m_observer = line.substr(pos_sep1+2, (pos_sep2-pos_sep1-3));
std::istringstream valuestr(line.substr(pos_sep2+1));
valuestr >> meas.m_value;
input_done = true;
}
// Reading an empty string will set std::ios::failbit, which we
// don't want to consider an error.
if (is.rdstate() == std::ios::failbit) is.clear();
if (! is.good()) input_done = true;
else
{
is.get(); // Skip past delimiter (newline).
is.clear(); // Be happy if it doesn't succeed.
}
}
return is;
}
int main(int argc, char *argv[])
{
typedef measurement measurement_t;
typedef std::vector measurement_container_t;
measurement_container_t measurements;
std::ifstream input;
if (argc <= 1)
{
std::cerr << "Usage: " << argv[0] << " "
<< std::endl;
return 1;
}
input.open(argv[1],std::ios::in);
if (!input)
{
std::cerr << argv[0] << ": Error: Cannot read from " << argv[1] << ": "
<< std::system_error(errno, std::system_category()).what()
<< "." << std::endl;
return 1;
}
while (input.good())
{
measurement_t meas;
input >> meas;
if (input.good()) measurements.push_back(meas);
}
std::cout << "Successfully read " << measurements.size() << " elements."
<< std::endl;
// Implicit template instantiation is playing here as well.
sort(measurements.begin(), measurements.end());
while (1) // Will exit with break;
{
measurement_t::value_type search_value;
std::cout << "Please enter a value to search for: ";
std::cin >> search_value;
if (! std::cin.good()) break;
measurement_t search_measurement(search_value,"N/A","N/A");
measurement_container_t::const_iterator found =
lower_bound(measurements.begin(), measurements.end(), search_measurement);
if (found->value() == search_value)
std::cout << "Found: " << *found << std::endl;
else
std::cout << "Value " << search_value << " not found." << std::endl;
}
return 0;
}