Dziugas
Dziugas

Reputation: 1570

Copying a file with streams in C++

I wrote this in an attempt to copy the contents of one text file into another based on command-line arguments:

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

using namespace std;

int main(int argc, char* argv[]) {

    if(argc != 3) {
        cout << "invalid args!";
        return 0;
    }

    fstream op(argv[1], ios::in);
    vector<string> list;

    string line;

    while(!op.end)
        op >> line;
        list.push_back(line);

    op.close();




    op.open(argv[2], ios::out);

    for(unsigned int i = 0; i < list.size(); i++)
        op << list[i];

    op.close();


    return 0;
}

It does not produce any syntax errors, but a logic error is evident: there is no output.

So apart from the lack of error-checking and the fact that there are more efficient ways to do this, what is wrong with my code? That is, why will it not copy file with name argv[1] to a file named argv[2]?

Upvotes: 0

Views: 332

Answers (3)

Adam Sosnowski
Adam Sosnowski

Reputation: 1284

For one-to-one copy, you may also consider the following code - handles binary data, uses less memory and is shorter:

#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>

using namespace std;


int main(int argc, char *argv[])
{
  if (argc < 3)
    return 1;

  fstream s(argv[1], ios::in);
  fstream d(argv[2], ios::out);

  copy(
      istreambuf_iterator<char>(s)
    , istreambuf_iterator<char>()
    , ostreambuf_iterator<char>(d));

  return 0;
}

Upvotes: 1

Christophe
Christophe

Reputation: 73376

There are several issues in your code:

  • With streams you shall not loop on end or eof (have a look at the many SO questions/answers about this).
  • The enclosing {} issue that Marcus revealed
  • You are not reading lines but words (operator>> uses spaces as separators) and squizing the whitespaces in the output.

Here how to tackle all this:

while(getline(op, line)) 
    list.push_back(line);

and of course for the output: op << list[i]<<endl;

Upvotes: 1

Marcus M&#252;ller
Marcus M&#252;ller

Reputation: 36347

You have a bug: your while loop's body is not enclosed in {}, so only op >> line is executed until the file is read completely, and the last value of line is then pushed onto the vector.

EDIT: By the way, that's a very good illustration for why you should let your editor do your code indentation; the way your while loop looked, it was hard to spot this mistake.

Upvotes: 3

Related Questions