C++ problem to write vector data to file
I want to write the content of the vector v to a file开发者_开发技巧. Problem is that not the content but the address will be placed inside the textfile.
When I write *pos inplace of &pos I get the error: error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'entry'
How does it work correct?
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <limits>
/*
Data.txt
John
6543
23
Max
342
2
A Team
5645
23
*/
struct entry
{
// passengers data
std::string name;
int weight; // kg
std::string group_code;
};
void reservations(std::vector<entry> v)
{
std::ofstream outfile;
outfile.clear();
outfile.open("reservations.txt");
// print data in vector
std::vector<entry>::iterator pos;
for (pos = v.begin(); pos!= v.end();++pos)
{
outfile << &pos << std::endl;
std::cout << &pos << std::endl;
}
outfile.close();
}
entry read_passenger(std::ifstream &stream_in)
{
entry passenger;
if (stream_in)
{
std::getline(stream_in, passenger.name);
stream_in >> passenger.weight;
stream_in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::getline(stream_in, passenger.group_code);
stream_in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
return passenger;
}
return passenger;
}
int main(void)
{
std::ifstream stream_in("data.txt");
std::vector<entry> v; // contains the reservations
std::vector<entry> a; // contains the cancellations
const int limit_total_weight = 10000; // kg
int total_weight = 0; // kg
entry current;
while (stream_in)
{
current = read_passenger(stream_in);
if (total_weight + current.weight >= limit_total_weight)
{
// push data (cancellations) to vector
a.push_back(current);
}
else
{
total_weight = total_weight + current.weight;
// push data (reservations) to vector
v.push_back(current);
}
}
reservations(v); // write reservations to file
std::cout << "Rest " << limit_total_weight - total_weight << "kg" <<std::endl;
return 0;
}
You should overload operator <<
for entry
:
std::ostream& operator << (std::ostream& o, const entry& e)
{
return o << e.name
<< " " << e.weight
<< " " << e.gruop_code;
}
Now you can write:
outfile << *pos << std::endl;
std::cout << *pos << std::endl;
First you were writing a pointer, and then you didn't tell C++ how an entry
should be represented in text.
Create an operator<<
overload for it.
Since entry
is a plain struct, and you haven't defined any operator<<
method to write its contents to an output stream, the compiler complains when you try to write out *pos
directly.
Either you need to define a suitable operator<<
method, or write out the members of the struct one by one, like
outfile << pos->name << std::endl;
outfile << pos->weight << std::endl;
outfile << pos->group_code << std::endl;
Try something like:
std::ostream& operator<<(std::ostream& os,const entry& toPrint)
{
os << "name :" << toPrint.name << '\n';
os << "weight :" << toPrint.weight << "(kg) \n";
os << "group_code :" << toPrint.group_code << '\n';
return os;
}
also you may want change the signature of the reservation function to
void reservations(const std::vector<entry>& v)
The reason your output looks like addresses with the present code is because you're outputting the address of the iterator.
The reason why you get the error "no operator found which takes a
right-hand operator of type 'entry'" is because there is no <<
operator which takes an entry
as its right hand operand. You can
easily define one:
std::ostream&
operator<<( std::ostream& dest, entry const& obj )
{
dest << obj.name;
return dest;
}
But this is a bit specialized; in other contexts, you might want to
output other fields of entry
. Classically, in fact, an operator<<
for entry
would output all relevant fields. An alternative solution
would be to define a transformer functional object, and use it:
struct EntryToName
{
std::string operator()( entry const& obj ) const
{
return obj.name;
}
};
Then in reservations
:
std::transform(
v.begin(), v.end(),
std::ostream_iterator<std::string>( outfile, "\n" ),
EntryToName() );
And BTW, it's generally considered preferrable to pass vectors by const reference, rather than by value.
You will either have to do outfile << pos->name << " " << pos->weight << /* etc */
, or implement a output operator, operator<<
.
It will look something like
std::ostream& operator<<(std::ostream& os, const entry&) {
return os << entry.name << " " << entry.weight << " " << entry.group_code;
}
Format as needed.
精彩评论