I need to revise this code to copy files using binary I/O

Pages: 12
This program is named CopyFile.cpp, which copies files using text I/O. I need to revise the following program so that it copies files using binary I/O.

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

int main()
{
//Enter a source file
cout << "Enter a source file name: ";
string inputFilename;
cin >> inputFilename;

//Enter a target file
cout << "Enter a target file name: ";
string outputFilename;
cin >> outputFilename;

//Create input and output streams
ifstream input(inputFilename.c_str());
ofstream output(outputFilename.c_str());

if (input.fail())
{
cout << inputFilename << " does not exist" << endl;
cout << "Exit program" << endl;
return 0;
}

char ch = input.get();
while (!input.eof()) // Continue if not end of file
{
output.put(ch);
ch = input.get(); // Read next character
}

input.close();
output.close();

cout << "\nCopy Done" << endl;

return 0;
}

Help please.
Well the first thing you need to know is that strings will mess with your binary data. So if you're going to store file data in ram, use a vector<char>
second: to output you can simply use the stream operator <<

Any further questions?
could you show me how that would look in the code please?
Sure, just a quick check that this isn't a homework assignment, and is for personal gain? (I doubt it is, if I really suspected I wouldn't inquire)
get/put work just fine for binary file copying. Just open both files in binary mode and you're fine.

Also there's no advantage to using vector<char> for strings. std::string pretty much is a vector<char> but with other things to make it more intuitive/easier to use for strings.
definitely not homework. I have been teaching myself C# out of a book for about a year now and thought it would be fun to learn c++...
@disch, except for a stupid little swap of return chars. Maybe it was my fault but every binary file I read into a string and passed through my sockets ended up with an extra couple bytes, or messed up code... With a vector<char> everything worked perfectly, and more swiftly for that matter.

edit: oh and yes, It was in ios::binary, probably still my fault
Last edited on
Could you both show me how your ideas look in code? I would like to know the best way to do this, you know, learn it right the first time rather than try to re-learn it later...
Disch's idea is almost guaranteed to work better than mine. But here you go:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   fstream fin;
   fin.open(filename.c_str(),ios::in|ios::binary);
   vector<char> fileBuf;
   fileBuf.reserve(65536); //the 65536 is a multiple of 8, I would change this to the file's size
   char buf = NULL;
   while (!fin.eof()) {
     buf = fin.get();
     if (!fin.eof())
       bufvec.push_back(buf);
   }
   fin.close();

   fstream os(filenameTwo.c_str(), ios::out | ios::binary );
   os.write( static_cast<char*>( &fileBuf.front() ), sizeof(char) * fileBuf.size() );
   os.close();


could either of you help?
jonsto wrote:
could either of you help?


lol impatient much? =)
sorry, I didn't think that the previous code would change very much...
*shrug*
If you need it spoonfed, email me.
that code is significantly different than the code I originally had. The code you did would be the input and output streams of my code I am trying to convert, correct?
@Disch what does your code look like and what are the benefits of doing that way as opposed to Ultifinitus's way?
@ultifinitus thanks for your help. I think my curiosity gets the best of me some times. I meant know offense by asking Disch his opinion. I am just trying to see all the different ways of doing things and decide for myself what I like and is most efficient.
No worries mate, "his" way isn't any different from "my" way, it's a simple swap of vector<char> to string, and the write to put. You could puzzle it out if you really wanted to.
Disch's idea is basically this:
1
2
3
//Create input and output streams
ifstream input(inputFilename.c_str(), ifstream::in | ifstream::binary);
ofstream output(outputFilename.c_str(), ofstream::out | ofstream::trunc | ofstream::binary);

so that is all I would have to change from the original code to convert binary files?
I don't really get it. If the OP original is to do a binary file copy then just use an array of bytes or int or whatever as the temporary buffer from source and copy to destination is enough. Why need vector<string> or other data structure to incur un-necessary cost ? Unless besides just blind binary copy the OP intent to do some processing on the read-in data ? Hmmm....
Pages: 12