Zach49899
Zach49899

Reputation: 21

Copying a file in C with fwrite

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);
}

Upvotes: 2

Views: 21669

Answers (4)

Raz Luvaton
Raz Luvaton

Reputation: 3770

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);

Upvotes: 1

Jerry Coffin
Jerry Coffin

Reputation: 490048

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);

Upvotes: 11

hd1
hd1

Reputation: 34657

Perhaps a look through an open-source copy tool in C would point you in the right direction.

Upvotes: 1

Musa
Musa

Reputation: 97672

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/

Upvotes: 1

Related Questions