Tamer Nemri
Tamer Nemri

Reputation: 29

C++ Read from file to vector

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

Answers (3)

James Kanze
James Kanze

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

Component 10
Component 10

Reputation: 10507

It looks like you don't need to use ofstreams 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

Syntactic Fructose
Syntactic Fructose

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

Related Questions