1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
#include <iostream>
#include <set>
#include <string>
#include <sstream>
#include <fstream>
struct person
{
// let us keep it simple for now
std::string first_name ; // invariant: no embedded spaces eg. "Bjarne"
std::string last_name ; // invariant: no embedded spaces eg. "Stroustrup"
std::string date_of_birth ; // invariant: no embedded spaces eg. "30-December-1950"
};
// write the information to an output stream as a single line of text
// first_name<space>last_name<space>date_of_birth
std::ostream& put_person( std::ostream& stm, const person& per )
{ return stm << per.first_name << ' ' << per.last_name << ' ' << per.date_of_birth ; }
// same as above, overloaded stream insertion operator
std::ostream& operator<< ( std::ostream& stm, const person& per )
{ return put_person( stm, per ) ; }
// read the information written with put_person from an input stream into per
std::istream& get_person( std::istream& stm, person& per )
{
std::string line ;
if( std::getline( stm >> std::ws, line ) ) // if a non-empty line of text was read successfully
{
std::istringstream strstm(line) ; // create a stream that reads from the line of text
// if first_name<space>last_name<space>date_of_birth<end_of_string> was successfully read, we are done
if( strstm >> per.first_name >> per.last_name >> per.date_of_birth ) return stm ;
}
// handle input failure
stm.clear( stm.failbit ) ; // put the stream into a failed state
return stm ; // and return it
}
// same as above, overloaded stream insertion operator
std::istream& operator>> ( std::istream& stm, person& per )
{ return get_person( stm, per ) ; }
// make the type person LessThanComparable
// keep it simple for now: compare only last_name, case-sensitive
bool operator< ( const person& a, const person& b ) { return a.last_name < b.last_name ; }
int main()
{
const std::string file_name = "heroes.txt" ;
{
// create a std::set of persons
// std::set an associative container that contains a sorted set of unique objects
// the default comparison function assumes that the type is LessThanComparable (uses the < operator)
// http://en.cppreference.com/w/cpp/container/set
std::set<person> heroes =
{
{ "Donald","Knuth", "January-10-1938" },
{ "Alan", "Kay", "May-17-1940" },
{ "Dennis", "Ritchie", "September-9-1941" },
{ "Ken", "Thompson", "February-4-1943" },
{ "Alan", "Kay", "May-17-1940" },
{ "Alex", "Stepanov", "November-16-1950" },
};
std::ofstream file(file_name) ; // open a file for writing
// http://www.stroustrup.com/C++11FAQ.html#for
for( const auto& hero : heroes ) file << hero << '\n' ; // write each person to the file
}
{
std::set<person> heroes ; // create an empty set of persons
{
std::ifstream file(file_name) ; // open the file for reading
person a_hero ;
while( file >> a_hero ) heroes.insert(a_hero) ; // insert each person read from the file into the set
}
// add stroustrup to the set of persons
// http://en.cppreference.com/w/cpp/container/set/insert
heroes.insert( { "Bjarne", "Stroustrup", "30-December-1950" } ) ;
// query on (case-sensitive) last name "Ritchie"
// http://en.cppreference.com/w/cpp/container/set/find
const auto iter = heroes.find( { "", "Ritchie", "" } ) ; // specify last name
if( iter != heroes.end() ) // if found, print last and first name, date of birth
std::cout << "found: " << iter->last_name << ", " << iter->first_name << " (born " << iter->date_of_birth << ")\n" ;
// print out the list of persons, sorted on last name
int n = 0 ;
std::cout << "\n----------\nheroes\n--------------\n" ;
for( const auto& hero : heroes ) std::cout << ++n << ". " << hero << '\n' ;
// write the updated list back to the file
{
std::ofstream file(file_name) ; // open a file for writing
for( const auto& hero : heroes ) file << hero << '\n' ; // write each person to the file
}
// print out the contents of the updated file
std::cout << "\n\n----------\ncontents of file '" << file_name << "'\n--------------\n\n"
<< std::ifstream(file_name).rdbuf() ;
}
}
|