Read File of Double Value into Object

I am using MS VS 2017 on Windows 10 Pro 64-bit. I am trying to accomplish this with c++11 standard features. I am asking in this forum because I have searched expensively and I cannot find and example which reads the data into an object with a member vector.

Below is some typical C++ code to read a text file of doubles in to a vector. This code works, as expected. The text file is passed at the command-line.

There is one double value per line in the file, as in:
1.111111
2.222222
3.333333
4.444444
5.555555

I would like to create a ClassA (for example) that has a method for reading the data in the file and populating the vector with double values.

class ClassA
{
public:
void addData( double ); // maybe even const double
//
// More code...
//

private:
vector<double> dataVector;
}

Will I be able to use the ifstream and istream_iterator instances to populate the vector in an object of ClassA ?

Or, am I going to have to do something similar to this pseudo-code:

For each number(n) in numbers:
dataObject.addData( n );


I would rather do this using the ifstream and istream iterator instances.

I have learned that the typical way of passing the ifstream instance to a method is to pass by reference.

Perhaps someone has a link to an example where this is done ??

Can anyone help me formulate a method to accomplish this ?


****************************************************************
****************************************************************
****************************************************************


#include <iostream>
#include <iterator>
#include <fstream>
#include <vector>
#include <algorithm> // for copy

using namespace std;

// Define the constants to manage command line arguments
const int CMD_ARG_FIL = 1;
const int CMD_ARG_MAX = 2;

int main( int argc, char *argv[] )
{
if ( argc == CMD_ARG_MAX )
{
ifstream inputStream( argv[ CMD_ARG_FIL ] );

if ( inputStream )
{

istream_iterator<double> start( inputStream ), end;

//
// Here I would like to populate the vector held in an object
//
vector<double> nos( start, end );

//
// NOTE: The rest of this code is just for checking and not what
// I intend to do with this ClassA object.
//
cout << "Read " << nos.size() << " numbers" << endl;

// Print the numbers read to stdout
cout << "Numbers read in:\n";
copy( nos.begin(), nos.end(),
ostream_iterator<double>( cout, "\n" ) );
cout << endl;

}
else
{
cout << "ERROR: File not found." << endl;
}
}
else
{
cout << "ERROR: Command line arguemnt mismatch." << endl;
}

system( "pause" );

}

Last edited on
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
struct A { 
  template <typename InputIterator>
  void add_data(InputIterator begin, InputIterator end) 
  { std::copy(begin, end, std::back_inserter(d)); }
  
  std::vector<double> d; 
};

// usually such a function is named operator<<.
std::ostream& print_me(std::ostream& str, A const& a) {
  // or, use std::ostream_iterator, if you prefer.
  for (auto const& elt: a.d) str << elt << '\n';
  return str;
}

int main() { 
  A a;
  
  {
    std::ifstream file("my-data.txt");
    using it = std::istream_iterator<double>;
    a.add_data(it{file}, it{}); 
  }
  
  if (print_me(std::cout, a)) std::cout << "\nprinting successful!\n"; 
}

Live demo:
http://coliru.stacked-crooked.com/a/05fdb60d0bf410ea
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;

using it = istream_iterator<double>;
using ot = ostream_iterator<double>;

class classA
{
   vector<double> dat;
public:
   classA( string filename ) { ifstream file( filename );   dat = vector<double>( it{file}, it{} ); }
   void print() { copy( dat.begin(), dat.end(), ot{ cout, "\n" } ); }
};

int main()
{
   classA a( "myfile.txt" );
   a.print();
}


1.11111
2.22222
3.33333
4.44444
5.55556

Ah, the wonders of floating-point precision on that last line!
Last edited on
Ah, the wonders of floating-point precision on that last line!
1
2
3
4
5
    void print()
    {
        cout.precision(7);
        copy( dat.begin(), dat.end(), ot{ cout, "\n" } );
    }
or
1
2
3
4
5
    void print()
    {
        cout << fixed;
        copy( dat.begin(), dat.end(), ot{ cout, "\n" } );
    }

1.111111
2.222222
3.333333
4.444444
5.555555
Ah, thanks @Chervil. I completely forgot that the default output precision was 6 sig figs, whilst the input file actually had 7. Mea culpa!
Thank you everyone, for your replies. I learned several things from your simplified examples.

ty mbozzi, for the simple solution and the operator overload.

ty lastchance, for creating an example using a constructor.

ty chervil, for an example that solves rounding with output problems.
Topic archived. No new replies allowed.