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
|
#include <iostream>
#include <utility>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream> // for testing
struct Info
{
// store several (name,age) pairs in a class.
using name_age_pair_t = std::pair<std::string,int> ;
std::vector<name_age_pair_t> several_pairs ;
// for testing
auto operator <=> ( const Info& ) const noexcept = default ;
};
// reading and writing using your own >> and << operators
// write out one name age pair
std::ostream& operator<< ( std::ostream& stm, const Info::name_age_pair_t& pair )
{
return stm << pair.first << '\n' // write the name (which may contain spaces) on line 1
<< pair.second << '\n' ; // write the age on line 2
}
// read in one name age pair
std::istream& operator>> ( std::istream& stm, Info::name_age_pair_t& pair )
{
std::getline( stm, pair.first ) ; // read in the name (which may contain spaces) from line 1
stm >> pair.second ; // read in the age from the next line
stm.ignore( 1'000'000, '\n' ) ; // extract and discard the new line at the end
return stm ;
}
// write out an Info object
std::ostream& operator<< ( std::ostream& stm, const Info& inf )
{
stm << inf.several_pairs.size() << '\n' ; // write out the number of pairs on the first line
// then write out each of the several (name,age) pairs in inf
for( const Info::name_age_pair_t& pair : inf.several_pairs ) stm << pair ;
return stm ;
}
// read into an Info object
std::istream& operator>> ( std::istream& stm, Info& inf )
{
Info temp ; // a temporary (empty) Info object
std::size_t n = 0 ; // the number of pairs to be read
stm >> n ;
stm.ignore( 1'000'000, '\n' ) ; // extract and discard the new line at the end
// try to read in n pairs into temp
Info::name_age_pair_t pair ;
for( std::size_t i = 0 ; i < n && stm >> pair ; ++i ) temp.several_pairs.push_back(pair) ;
if( temp.several_pairs.size() == n ) // if n pairs were correctly read
{
// success! update inf with what was read in
using std::swap ;
swap( inf, temp ) ;
}
else stm.setstate( std::ios_base::failbit ); // failed! indicate failure
return stm ;
}
int main() // minimal test driver
{
const Info inf { { { "abc def", 12 }, { "ghij kl", 34 }, { "mno pqr stu", 55 } } } ;
std::cout << inf ;
{
std::ostringstream ostm ;
ostm << inf ;
std::istringstream istm( ostm.str() ) ;
Info inf2 ;
if( istm >> inf2 && inf2 == inf ) std::cout << "\n*** ok ***\n" ;
else std::cerr << "\n*** error ***: something is wrong\n" ;
}
}
|