Copying a file in C with fwrite

18,675

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/

Share:
18,675
Zach49899
Author by

Zach49899

Updated on June 04, 2022

Comments

  • Zach49899
    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);
    }
    
    • Jack
      Jack over 11 years
      In your fwrite() call,the first paramenter should be a pointer to file contents in memory(which I don't see here where you read) instead of fi itself.
    • alhelal
      alhelal over 6 years
      @Zach49899 you can use open(), read(), write() system call. it's more easy.
  • hd1
    hd1 over 11 years
    And 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
    Zach49899 over 11 years
    Do 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
    Musa over 11 years
    You have the general idea, for large files you'd have to do it in pieces though.
  • Zach49899
    Zach49899 over 11 years
    Is 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
    Orion over 11 years
    Nice found. Zach49899: take look at the copy function.
  • Sven Bamberger
    Sven Bamberger about 8 years
    isn't there a ')' missing at the end of the while?
  • Jerry Coffin
    Jerry Coffin about 8 years
    @SvenBamberger: Oops, yup, looks like there was. Thanks.
  • alhelal
    alhelal over 6 years
    @JerryCoffin will it work for non regular file also?
  • Jerry Coffin
    Jerry Coffin over 6 years
    @alhelal: What sort of "non regular file" did you have in mind?
  • alhelal
    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
    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, and fopen(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
    alhelal over 6 years
    @JerryCoffin I don't understand your response. I told you for .pdf, docx not for binary.
  • Jerry Coffin
    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.