简体   繁体   中英

Reading input file and storing them in STL vector in C++

I am trying to read input from a file and trying to store in a vector called x_channel. I am trying to use copy function but its not copying the content of file into x_channel vector. The code I am using to populate the vector is copy(in_iter, eof,back_inserter(x_channel)).

I tried to mimic this code from read integers from a file into a vector in C++ .

Many THanks

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

using namespace std;

int main() {
    ifstream infile("channels.txt",ios::in);
    
    // Get input stream and end of stream iterators 
    istream_iterator<double> in_iter(infile);
    istream_iterator<double> eof;

    // Get output stream iterators 
    ostream_iterator<double> cout_it(cout, " ");
    vector<double> x_channel;

   // We have both input and output iterators, now we can treat them // as containers. Using copy function we transfer data from one     // container to another.     // Copy elements from input to output using copy functio
    copy(in_iter, eof, cout_it);


    // Copy elements from input to vector using copy function
    copy(in_iter, eof,back_inserter(x_channel));

    cout << "\n";

    copy(x_channel.begin(), x_channel.end(), ostream_iterator<double>(cout, "\n"));

    cout << " " << endl;
    cout << "\n";

    infile.close();
        return 0; }

The 1st copy() is reading values from infile and printing them to std::cout . That is advancing the file's read pointer towards the end of the file. So there is no more data for the 2nd copy() to read from infile to push into x_channel . You would need to seek infile back to the beginning of the file to re-read the same values again.

Also, std::istream_iterator is a single-pass iterator anyway, so you can't reuse it to read the same data multiple times. You would need to use a new std::istream_iterator instance after seeking the file backwards.

Try this instead:

int main() {
    ifstream infile("channels.txt");
    vector<double> x_channel;
    
    copy(
        istream_iterator<double>(infile),
        istream_iterator<double>(),
        ostream_iterator<double>(cout, " ")
    );

    infile.seekg(0);

    copy(
        istream_iterator<double>(infile),
        istream_iterator<double>(),
        back_inserter(x_channel)
    );

    cout << "\n";

    copy(
        x_channel.begin(),
        x_channel.end(),
        ostream_iterator<double>(cout, "\n")
    );

    cout << " " << endl;
    cout << "\n";

    infile.close();
    return 0;
}

Or, like @MooingDuck suggested, simply don't read from infile multiple times to begin with, just read from it one time into x_channel , and then use x_channel as needed (do you really need repeat copies of the same data on cout with different delimiters?), eg:

int main() {
    ifstream infile("channels.txt");

    vector<double> x_channel;
    copy(
        istream_iterator<double>(infile),
        istream_iterator<double>(),
        back_inserter(x_channel)
    );

    /* alternatively:
    vector<double> x_channel(
        istream_iterator<double>(infile),
        istream_iterator<double>()
    );
    */

    infile.close();

    // omit this if you don't really need it...
    copy(x_channel.begin(), x_channel.end(), ostream_iterator<double>(cout, " "));

    cout << "\n";

    copy(x_channel.begin(),x_channel.end(), ostream_iterator<double>(cout, "\n"));

    cout << " " << endl;
    cout << "\n";

    return 0;
}

You don't need to "copy" the files to a vector. "Copying" means creating a duplicate of something. What you want to do is simple "read the file and store the data in a vector container".

That is pretty simple done like this minimal executable example shows:

#include <iostream>
#include <fstream>
#include <vector>

#define FILENAME "channels.txt"

int main()
{
  std::fstream infile;
  std::vector<double> xChannel;

  xChannel.push_back(123);
  xChannel.push_back(456);

  //Print vector
  for(double element : xChannel)
    std::cout << element << std::endl;

  //Write data to file for testing purpose
  infile.open(FILENAME, std::ios::out);
  if(!infile.is_open())
    std::cout << "Could not open file!" << std::endl;

  //write elements to file with for:each loop
  for(double element : xChannel)
    infile << element << std::endl;

  //Close file
  infile.close();
  //Delete vector items for proof of conecpt
  xChannel.clear();

  //Read data back into vector from file
  infile.open(FILENAME, std::ios::in);
    if(!infile.is_open())
      std::cout << "Couldnot open file!" << std::endl;

  //Read data back to vector
  double value{};
  while(infile >> value){
    xChannel.push_back(value);
  }
  //Close file
  infile.close();

  //Print vector
  for(double element : xChannel)
    std::cout << element << std::endl;

  std::cin.get();
  return 0;
}

Once you red in the data you can deal with the vector as you please, as well as copying (duplicating) the values.

You find the methods you can use on the std::vector class here . Fe to sorting the vector is simply done with the line of code std::sort(xChannel.begin(), xChannel.end()); You will have much fun with that:)

Btw. for reading in the full line you can use std::getline() - it will get you the whole line of code from a file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM