No. Do not give up. Use the C++ approach. Although I will also use std::getline, I think it is rather C-Style. And therefor I will wrap this functrion in a proxy class.
I find your idea good, to use a std::istream_iterator. This is the "more modern" C++ way of doing things. And the big advantage is that you can use the istream_iterator in algorithms.
The only problem to solve is, to implement the abstract model of a "line" into a class. And as I will show below that is fairly easy.
Using a proxy class is the standard approach and you will find a lot of examples here on SO doing exactly that.
Please see:
#include <vector>
#include <string>
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <sstream>
#include <ios>
std::istringstream testFile{R"(Line1Word1 Line1Word2 Line1Word3
Line2Word1 Line2Word2
Line3Word1 Line3Word2 Line3Word3 Line3Word4
Line4Word1 Line4Word2 Line4Word3
)"};
struct Line // ! This is a proxy for the input_iterator and output iterator!
{
// Input function. Read on line of text file and split it in columns
friend std::istream& operator>>(std::istream& is, Line& line) {
return std::getline(is, line.lineTemp );
}
// Output function.
friend std::ostream& operator<<(std::ostream& os, const Line& line) {
return os << line.lineTemp;
}
// cast to needed result
operator std::string() const { return lineTemp; }
// Temporary Local storage for line
std::string lineTemp{};
};
int main()
{
std::cout << "\n\nTest 1. Read all lines into a vector:\n";
std::vector<std::string> allLines {std::istream_iterator<Line>(testFile),std::istream_iterator<Line>() };
std::copy(allLines.begin(), allLines.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
std::cout << "\n\nTest 2: Display fist 2 in file\n";
testFile.clear(); testFile.seekg(0,std::ios::beg);
std::copy_n(std::istream_iterator<Line>(testFile),2,std::ostream_iterator<std::string>(std::cout, "\n"));
testFile.clear(); testFile.seekg(0,std::ios::beg);
std::cout << "\n\nTest 3: Number of lines in File\n"
<< std::distance(std::istream_iterator<Line>(testFile),std::istream_iterator<Line>());
std::cout << "\n\nTest 4: Use iterator separately\n";
testFile.clear(); testFile.seekg(0,std::ios::beg);
// Define the iterator
std::istream_iterator<Line> lineIterator(testFile);
// Dereference iterator
std::cout << *lineIterator << "\n";
return 0;
}
std::getlinedoes. Use the right tool, for the right job. And the right tool for this job is not a stream iterator butstd::getline.