-1

I've a multiline file, every line a string.

Example of code.txt:

AAAAA
BB33A
C544W

I have to put some code contained in another file before every string. I'm using this:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main()
{
    //the file to include before every string
    ifstream one("1.txt");

    //final output file
    ofstream final;
    final.open ("final.txt", ofstream::app);

    //string file
    string line;
    ifstream file("code.txt");

    while (getline(file,line))
    {
       final<<one.rdbuf();
       final<<line;
    }
}

Now, this doesn't work, it works only for the first line of code.txt. What is wrong?

Northumber
  • 175
  • 1
  • 2
  • 14
  • Why are you using the buffer to read the file? That seems like a super bad idea. – tadman Aug 31 '17 at 18:22
  • I found this on the c++ reference, i don't know what to use, please advise me how @tadman – Northumber Aug 31 '17 at 18:26
  • 1.txt have the same lines as code.txt, or just 1 line, or you have to put the entire file before each line of code.txt? – Check Aug 31 '17 at 18:28
  • To copy the file in large chunks, irrespective of lines, use [`read`](http://en.cppreference.com/w/cpp/io/basic_istream/read). To copy it line-by-line use [`getline`](http://en.cppreference.com/w/cpp/io/basic_istream/getline). The buffer object should be left alone unless you are doing something really unusual. – tadman Aug 31 '17 at 18:31
  • The entire file before each line @Check – Northumber Aug 31 '17 at 18:31
  • @Northumber why use rdbuf inside the loop then, I mean, read one time the 1.txt file and use it. – Check Aug 31 '17 at 18:32
  • with the read() function as tadman suggests? @Check – Northumber Aug 31 '17 at 18:34
  • @Northumber I answer you with an example. – Check Aug 31 '17 at 18:45

2 Answers2

2

final<<one.rdbuf() works for only the first line because once you stream out the rdbuf the first time, its read pointer is sitting at the end of the 1.txt file data. There is no data left for it to read on subsequent streaming. You would have to reset the one stream back to the beginning of its data on each loop iteration, eg:

while (getline(file,line))
{
   final<<one.rdbuf();
   final<<line;
   one.seekp(0); // <-- add this
}

Otherwise, do as @Check suggests. Read the content of the 1.txt file into memory one time, and then stream that out on each loop iteration, instead of re-reading the file on each iteration.

Remy Lebeau
  • 454,445
  • 28
  • 366
  • 620
1

I would change your final<<one.rdbuf();. You can use this:

//the file to include before every string
ifstream one("1.txt");

std::string first;
if (one.is_open())
{
    // file length and reserve the memory.
    one.seekg(0, std::ios::end);
    first.reserve(static_cast<unsigned int>(one.tellg()));
    one.seekg(0, std::ios::beg);

    first.assign((std::istreambuf_iterator<char>(one)),
                 (std::istreambuf_iterator<char>()));

    one.close();
}

//final output file
ofstream final;
final.open ("final.txt", ofstream::app);

//string file
string line;
ifstream file("code.txt");

while (getline(file,line))
{
    final<<first;
   final<<line;
}

Maybe you want to check this https://stackoverflow.com/a/8737787/3065110

Check
  • 93
  • 1
  • 9