Copying a file in C with fwrite
Solution 1
This isn't how fwrite
works.
To copy a file, you'd typically allocate a buffer, then use fread
to read one buffer of data, followed by fwrite
to write that data back out. Repeat until you've copied the entire file. Typical code is something on this general order:
#define SIZE (1024*1024)
char buffer[SIZE];
size_t bytes;
while (0 < (bytes = fread(buffer, 1, sizeof(buffer), infile)))
fwrite(buffer, 1, bytes, outfile);
Solution 2
Perhaps a look through an open-source copy tool in C would point you in the right direction.
Solution 3
Here is How It can be done:
Option 1: Dynamic "Array"
Nested Level: 0
// Variable Definition
char *cpArr;
FILE *fpSourceFile = fopen(<Your_Source_Path>, "rb");
FILE *fpTargetFile = fopen(<Your_Target_Path>, "wb");
// Code Section
// Get The Size Of bits Of The Source File
fseek(fpSourceFile, 0, SEEK_END); // Go To The End Of The File
cpArr = (char *)malloc(sizeof(*cpArr) * ftell(fpSourceFile)); // Create An Array At That Size
fseek(fpSourceFile, 0, SEEK_SET); // Return The Cursor To The Start
// Read From The Source File - "Copy"
fread(&cpArr, sizeof(cpArr), 1, fpSourceFile);
// Write To The Target File - "Paste"
fwrite(&cpArr, sizeof(cpArr), 1, fpTargetFile);
// Close The Files
fclose(fpSourceFile);
fclose(fpTargetFile);
// Free The Used Memory
free(cpArr);
Option 2: Char By Char
Nested Level: 1
// Variable Definition
char cTemp;
FILE *fpSourceFile = fopen(<Your_Source_Path>, "rb");
FILE *fpTargetFile = fopen(<Your_Target_Path>, "wb");
// Code Section
// Read From The Source File - "Copy"
while(fread(&cTemp, 1, 1, fpSourceFile) == 1)
{
// Write To The Target File - "Paste"
fwrite(&cTemp, 1, 1, fpTargetFile);
}
// Close The Files
fclose(fpSourceFile);
fclose(fpTargetFile);
Solution 4
The first parameter of fwrite is a pointer to the data to be written to the file not a FILE* to read from. You have to read the data from the first file into a buffer then write that buffer to the output file. http://www.cplusplus.com/reference/cstdio/fwrite/
Zach49899
Updated on June 04, 2022Comments
-
Zach49899 almost 2 years
I am new to C and was trying to write a program just to copy a file so that I could learn the basics of files. My code takes a file as input, figures out its length by subtracting its start from its end using fseek and ftell. Then, it uses fwrite to write, based on what I could get from its man page, ONE element of data, (END - START) elements long, to the stream pointed to by OUT, obtaining them from the location given by FI. The problem is, although it does produce "copy output," the file is not the same as the original. What am I doing wrong? I tried reading the input file into a variable and then writing from there, but that didn't help either. What am I doing wrong? Thanks
int main(int argc, char* argv[]) { FILE* fi = fopen(argv[1], "r"); //create the input file for reading if (fi == NULL) return 1; // check file exists int start = ftell(fi); // get file start address fseek(fi, 0, SEEK_END); // go to end of file int end = ftell(fi); // get file end address rewind(fi); // go back to file beginning FILE* out = fopen("copy output", "w"); // create the output file for writing fwrite(fi,end-start,1,out); // write the input file to the output file }
Should this work?
{ FILE* out = fopen("copy output", "w"); int* buf = malloc(end-start); fread(buf,end-start,1,fi); fwrite(buf,end-start,1,out); }
-
hd1 over 11 yearsAnd for the lot of you who think that this isn't an answer, if I can figure out how to embed links in comments, I'd be happy to convert it to a comment.
-
Zach49899 over 11 yearsDo you mean like this? FILE* out = fopen("copy output", "w"); int* buf = malloc(end-start); fread(buf,end-start,1,fi); fwrite(buf,end-start,1,out);
-
Musa over 11 yearsYou have the general idea, for large files you'd have to do it in pieces though.
-
Zach49899 over 11 yearsIs there any way you can create a pointer that points to an mallocate-d address to just store 0's and 1's without it caring about what they represent? The buffer way works for small files, but for large files I think the error comes in that I tried to store thousands of bytes as a single int.
-
Orion over 11 yearsNice found.
Zach49899
: take look at the copy function. -
Sven Bamberger about 8 yearsisn't there a ')' missing at the end of the while?
-
Jerry Coffin about 8 years@SvenBamberger: Oops, yup, looks like there was. Thanks.
-
alhelal over 6 years@JerryCoffin will it work for non regular file also?
-
Jerry Coffin over 6 years@alhelal: What sort of "non regular file" did you have in mind?
-
alhelal over 6 years@JerryCoffin forget the term "non regular file". I actually want to know for
.pdf,.docx
(I say these are non regular, but these are also regular) etc. files. -
Jerry Coffin over 6 years@alhelal: be sure when you open the files that you specify "binary", so
fopen(filename, "rb");
for the file you're reading, andfopen(filename, "wb");
for the file you're writing. This is crucial for portable code, though on some OSes (e.g., Linux) it makes no real difference. -
alhelal over 6 years@JerryCoffin I don't understand your response. I told you for
.pdf, docx
not for binary. -
Jerry Coffin over 6 years@alhelal: Files fall into two categories: text, and binary. Anything that's not plain text is binary, so those are binary.