Reputation: 29
I'm trying to convert a string streamed phone lookup program into file streamed.. I'm missing something, but I'm stuck.. what members can I use in the ofstream process to get this working?
ofstream& process (ofstream &os, vector<PersonInfo> people)
{
// for each entry in people
for (vector<PersonInfo>::const_iterator entry = people.begin();
entry != people.end(); ++entry) {
ofstream formatted, badNums; // objects created on each loop
// for each number
for (vector<string>::const_iterator nums = entry->phones.begin();
nums != entry->phones.end(); ++nums) {
if (!valid(*nums)) {
badNums << " " << *nums; // string in badNums
} else
// ``writes'' to formatted's string
formatted << " " << format(*nums);
}
if (badNums.empty()) // there were no bad numbers
os << entry->name << " " // print the name
<< formatted.str() << endl; // and reformatted numbers
else // otherwise, print the name and bad numbers
cerr << "input error: " << entry->name
<< " invalid number(s) " << badNums.str() << endl;
}
return os;
}
Upvotes: 2
Views: 473
Reputation: 154027
First, you don't want an ofstream
, except at the point you're opening
the file (creating the instance). The output stream interface is
defined by std::ostream
; std::ofstream
derives from this, as does
std::ostringstream
(output can become an std::string
), and in most
applications, a couple of others written by the local programmers. In
your case (if I've understood the problem correctly), what you want is:
std::ostream& process( std::ostream& os,
std::vector<PersonInfo> const& people )
// Note the use of a const reference above. No point
// in copying the entire vector if you're not going to
// modify it.
{
for ( std::vector<PersonInfo>::const_iterator entry = people.begin();
entry != people.end();
++ entry ) {
std::ostringstream formatted;
std::ostringstream badNums;
// ...
if ( badNums.str().empty() ) {
os << ... << formatted.str() << std::endl;
} else {
os << ... << badNums.str() << std::endl;
}
}
return os;
}
Note the different types: std::ostream
formats output, independently
of the destination type. std::ofstream
derives from it, and provides
a file as destination. std::ostringstream
derives from it, and
provides a std::string
as destination type. And the std::ostream
takes a std::streambuf*
as argument, and you provide the destination
type.
Upvotes: 4
Reputation: 10507
It looks like you don't need to use ofstream
s for the internal parts of this function. In fact you don't need to use streams at all, a std::string
would do:
ofstream& process (ofstream &os, vector<PersonInfo> people)
{
// for each entry in people
for (vector<PersonInfo>::const_iterator entry = people.begin();
entry != people.end(); ++entry) {
string formatted, badNums; // objects created on each loop
// for each number
for (vector<string>::const_iterator nums = entry->phones.begin();
nums != entry->phones.end(); ++nums) {
if (!valid(*nums)) {
badNums += " " + *nums; // string in badNums
} else
// ``writes'' to formatted's string
formatted += " " + format(*nums);
}
if (badNums.empty()) // there were no bad numbers
os << entry->name << " " // print the name
<< formatted << endl; // and reformatted numbers
else // otherwise, print the name and bad numbers
cerr << "input error: " << entry->name
<< " invalid number(s) " << badNums << endl;
}
return os;
}
Upvotes: 0
Reputation: 20124
You never associate a file with ostream, so the compiler doesn't know what to do with the data you write into it.
ofstream& process (ofstream &os, vector<PersonInfo> people)
{
os.open("Data.txt"); //open file to be used
if(!os.is_open())
std::cerr << "Error opening file!\n";
//rest of code goes here
}
EDIT: after reading through your program again, i noticed you're using ofstream wrong. Ofstream is for opening and writing FILES.The program has a lot of syntax and logical errors i would read up on it more here.
Upvotes: 0