Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can't I use ifstream in a function that called for istream as a parameter?

Tags:

c++

ifstream

This is the drill for Chapter 10 in Programming Principles and Practice Using C++. The program work with points:

  1. it prompt the user to input (x,y) pairs. They are then stored in a vector of Points called original_points.
  2. the original points are printed to a file
  3. the program then read the file to retrieve the same points, stored in a vector of points called processed_points
  4. the two vectors are compared, if they are not the same, the program throws an error.

The problem is that the processed_points has a size() of 0, that happens only when I use get_vector_points() to get those points. What is wrong with the function?

//put any vector points from ist into points
void get_vector_points(istream& ist, vector<Point>& points)
{
    //this function is bad, it doesn't do anything the second time you use it
    while(true)
    {
        Point p;
        if( ist >> p)
            points.push_back(p);
        else return;
    }
}
//
void write_to_file(string& path, vector<Point>& v_of_points)
{
    //open output file
    ofstream ofile(path);

    //output results to file
    for(Point p : v_of_points)
    {
        ofile << p <<endl;
    }

    //close output stream
    ofile.close();
}
void read_from_file(string& path, vector<Point>& v_of_points)
{
    //open input file
    ifstream ifile(path);

    //read from file : Here comes trouble
    get_vector_points(ifile, v_of_points);

    //But no problem if you do the following instead
    //    while(true)
    //    {
    //        Point p;
    //        if( ifile >> p)
    //            v_of_points.push_back(p);
    //        else break;
    //    }
}
//read point from specified istream ist, format:(0,0)
//output points from specified ostream ost, format:(0,0)
void points_drill(string path)
{
    //read from console a vector of points
    vector<Point> original_points;
    get_vector_points(cin, original_points);

    //write the same vector to file
    write_to_file(path,original_points);

    //read the same vector from file, but call it processed
    vector<Point> processed_points;
    read_from_file(path,original_points);

    //they should be the same
    for (int i= 0; i < original_points.size(); i++)
    {
        if (original_points.size()!=processed_points.size())
            throw runtime_error("Size Mismatch"); //error here and proccesed_point has size of 0
        if (original_points[i]!=processed_points[i])
            throw runtime_error("something is wrong!");
    }
}

Note that I'm using a custom Point. Full code is available at http://pastebin.com/ZvfcZxf3

Any comment on the coding style/readability is appreciated.

like image 262
tomtclai Avatar asked Mar 19 '23 12:03

tomtclai


2 Answers

The call

read_from_file(path,original_points);

is reading into the vector original_points, not processed_points

like image 181
wakjah Avatar answered May 03 '23 20:05

wakjah


You should try a different way to read in the file:

void get_vector_points(istream& ist, vector<Point>& points)
{
   std::string line;
   std::string first, second;
   while(std::getline(ist,line)) 
   // this should get every line in the file as a string.
   // if the formatting of the file is 2 doubles per line.
   // You will need to do the parsing yourself by grabbing each value
   {
   // example first line:    123   321
    first = line.split[0]; // this is not a real function this is just Psudo code
    //first = "123"
    second = line.split[1];// for parsing text and splitting into 2 doubles
    // second = "321"
    Point p;
    p.x = atoi(first); // atoi is = ascii to int.  Makes a string intager into a 
    p.y = atoi(second);// actual int data type
    // p.x = 123   p.y = 321
    points.push_back(p)
    else return;
   }
}
like image 24
Jay Avatar answered May 03 '23 20:05

Jay