Reputation: 671
I have written a code to read from a array of file in c which is something like below and it works fine.
I am trying to replicate it in C++ and use ifstream for array of files and trying to read one line from a file a time like I am doing in C. However with ifstream I am unable to move ahead.
I have ifstream files[] pointer from a function which would point me to first file
Below Code reads one line from each file at a time and keeps looping
char *filename[] = {"mFile1.txt", "mFile2.txt", "mFile3.txt", "mFile4.txt"};
char line[1000];
FILE *fp[count];
unsigned int loop_count;
const int num_file = count;
char **temp = filename;
FILE *ffinal = fopen("scores.txt", "ab+");
for (loop_count = 0; loop_count < count; loop_count++)
{
if ((fp[loop_count] = fopen(*temp,"r")) != NULL)
{
// printf("%s openend successfully \n",*temp);
}
else
{
printf("error file cannot be opened \n");
exit(1);
}
temp++;
}
do
{
for (loop_count = 0; loop_count < num_file; loop_count++)
{
memset(line, 0, sizeof(line));
if (fgets(line, sizeof(line), fp[loop_count]) != NULL)
{
/* --- Code in C++ where I get stuck with ifstream and getline */ it errors out with getline saying too few arguments
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <new>
#include <sstream>
#include <string>
using namespace std;
ifstream *OpenFiles(char * const fileNames[], size_t count);
int main (void)
{
char line[1000];
char * const fileNames[] = {"abc.txt", "def.txt", "ghi.txt"};
ifstream *pifstream = OpenFiles(fileNames, 3);
for (int i = 0; i < 3; i++)
{
getline(pifstream[i], line);
}
return 0;
}
ifstream *OpenFiles(char * const fileNames[], size_t count)
{
ifstream *pifstream = new (nothrow) ifstream[count];
ifstream *preturn;
preturn = pifstream;
if (pifstream == NULL)
{
cerr << "error opening the file";
}
for (int elem = 0; elem < count; elem++)
{
pifstream[elem].open(fileNames[elem]);
if (!pifstream)
{
cerr << "existing with error ";
exit(1);
}
}
return preturn;
}
Upvotes: 1
Views: 1361
Reputation: 2705
#include <array> // Constant size container
#include <vector> // Dynamic size container
#include <fstream> // File I/O
#include <stdexcept> // Stock exceptions
#include <iostream> // Standard I/O streams
// Program entry
int main(){
// Like C array, but with useful member functions
const std::array<const char*, 3> filenames{"test1.txt", "test2.txt", "test3.txt"};
// Still empty vector of input file streams
std::vector<std::ifstream> files;
// Iterate through filenames, one-by-one
for(auto filename : filenames){
// Create input file stream in-place at end of vector
files.emplace_back(filename);
// Last input file stream in vector (see line above) is with error (opening failed)
if(!files.back())
// Throw error upwards (there's no catch, so the host, like the console, reports the exception message)
throw std::runtime_error("Couldn't open file: " + std::string(filename));
}
// Line buffer
std::string line;
// Just loop 3 times (for lines)
for(unsigned line_i = 0; line_i < 3; ++line_i)
// Iterate through file streams
for(auto& file : files)
// Get current line from file stream (moves file pointer behind line + separator) and check stream status (if stream is EOF, the condition goes 'false' and nothing further happens)
if(std::getline(file, line))
// Write line number, character ':' and gotten line to standard output
std::cout << line_i << ':' << line << std::endl;
// Program exit status (usually 0 == OK)
return 0;
}
Safe, fast, simple. This code requires C++11 (which shouldn't be a problem these days anymore) and hasn't any additional dependency, just STL.
Upvotes: 3