Thread: Copying file contents with f-read and f-write

  1. #1
    Registered User
    Join Date
    Mar 2024
    Posts
    20

    Copying file contents with f-read and f-write

    So I want to reada file's contents and write it to another one, overwriting it so the two have identical contents. And I would like to use a buffer so I'm trying to do this with fread() and fwrite():

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    
    void exit_with_msg(const char *s) {
        (void) fputs(s, stderr);
        
        exit(EXIT_FAILURE);
    }
    
    
    
    int copy(FILE *src, FILE *dst) {
        if (src == (FILE *)0 || dst == (FILE *)0) {
            return -1;
        }
        
        unsigned char buf[512];
        size_t n;
        
        while ((n = fread(buf, 512, 1, src)) > 0) {
            if (fwrite(buf, 512, 1, dst) != n) {
                return -2;
            }
        }
        
        if (ferror(src) != 0) {
            return -1;
        }
        
        return 0;
    }
    
    
    
    int main(void) {
        FILE *src = fopen("srcfile", "rb");
        if (src == (FILE *)0) {
            exit_with_msg("Couldn't open source file\n");
        }
        
        FILE *dst = fopen("dstfile", "wb");
        if (dst == (FILE *)0) {
            (void) fclose(src);
            
            exit_with_msg("Couldn't open destination file\n");
        }
        
        int status = copy(src, dst);
        
        if (status != 0) {
            (void) fclose(src);
            (void) fclose(dst);
            
            char *s = "Couldn't write file contents.\n";
            
            if (status == -1) {
                s = "Couldn't read file contents.\n";
            }
            
            exit_with_msg(s);
        }
        
        (void) fclose(src);
        (void) fclose(dst);
        
        return 0;
    }
    But this doesn't copy the whole contents. For example if srcfile had this:
    Code:
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam placerat at
    sapien sit amet efficitur. Phasellus id sem vel arcu laoreet malesuada. Quisque
    elementum malesuada massa, ac convallis ante fringilla quis. Proin elementum
    metus ac rutrum pharetra. Fusce et justo suscipit, pellentesque ipsum sed,
    imperdiet lectus. In tortor elit, accumsan nec dolor eget, scelerisque fermentum
    ipsum. Vestibulum sit amet imperdiet ipsum. Sed ornare, mauris at lobortis
    porttitor, augue nisi vestibulum ipsum, non lobortis arcu neque posuere nibh.
    Proin ac justo vel ipsum interdum mollis ac vitae tortor. Orci varius natoque
    penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean
    aliquam dignissim risus, in malesuada nibh auctor sed.
    The contents of dstfile would be this:
    Code:
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam placerat at
    sapien sit amet efficitur. Phasellus id sem vel arcu laoreet malesuada. Quisque
    elementum malesuada massa, ac convallis ante fringilla quis. Proin elementum
    metus ac rutrum pharetra. Fusce et justo suscipit, pellentesque ipsum sed,
    imperdiet lectus. In tortor elit, accumsan nec dolor eget, scelerisque fermentum
    ipsum. Vestibulum sit amet imperdiet ipsum. Sed ornare, mauris at lobortis
    porttitor, augue nisi vestibulum ipsum, non lob
    And I figured it's copying just the first 512 bytes because if fread() is passed 1 as the nitems aguments it returns 0 if the read is incomplete (incomplete meaning it didn't read exactly 512 bytes), so I passed 1 to the size argument and 512 to the nitems arguments:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    
    void exit_with_msg(const char *s) {
        (void) fputs(s, stderr);
        
        exit(EXIT_FAILURE);
    }
    
    
    
    int copy(FILE *src, FILE *dst) {
        if (src == (FILE *)0 || dst == (FILE *)0) {
            return -1;
        }
        
        unsigned char buf[512];
        size_t n;
        
        while ((n = fread(buf, 1, 512, src)) > 0) {
            if (fwrite(buf, 1, 512, dst) != n) {
                return -2;
            }
        }
        
        if (ferror(src) != 0) {
            return -1;
        }
        
        return 0;
    }
    
    
    
    int main(void) {
        FILE *src = fopen("srcfile", "rb");
        if (src == (FILE *)0) {
            exit_with_msg("Couldn't open source file\n");
        }
        
        FILE *dst = fopen("dstfile", "wb");
        if (dst == (FILE *)0) {
            (void) fclose(src);
            
            exit_with_msg("Couldn't open destination file\n");
        }
        
        int status = copy(src, dst);
        
        if (status != 0) {
            (void) fclose(src);
            (void) fclose(dst);
            
            char *s = "Couldn't write file contents.\n";
            
            if (status == -1) {
                s = "Couldn't read file contents.\n";
            }
            
            exit_with_msg(s);
        }
        
        (void) fclose(src);
        (void) fclose(dst);
        
        return 0;
    }
    But now the contents of dstfile is this:
    Code:
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam placerat at
    sapien sit amet efficitur. Phasellus id sem vel arcu laoreet malesuada. Quisque
    elementum malesuada massa, ac convallis ante fringilla quis. Proin elementum
    metus ac rutrum pharetra. Fusce et justo suscipit, pellentesque ipsum sed,
    imperdiet lectus. In tortor elit, accumsan nec dolor eget, scelerisque fermentum
    ipsum. Vestibulum sit amet imperdiet ipsum. Sed ornare, mauris at lobortis
    porttitor, augue nisi vestibulum ipsum, non lobortis arcu neque posuere nibh.
    Proin ac justo vel ipsum interdum mollis ac vitae tortor. Orci varius natoque
    penatibus et magnis dis parturient montes, nascetur ridiculus mus. Aenean
    aliquam dignissim risus, in malesuada nibh auctor sed.
    s ac rutrum pharetra. Fusce et justo suscipit, pellentesque ipsum sed,
    imperdiet lectus. In tortor elit, accumsan nec dolor eget, scelerisque fermentum
    ipsum. Vestibulum sit amet imperdiet ipsum. Sed ornare, mauris at lobortis
    porttitor, augue nisi vestibulum ipsum, non lob
    So now it's reading the entire contents of srcfile, but instead of stopping when it reaches EOF, it goes back 425 bytes from the end of the file to read exactly another 512 byes???? Why is it doing that?? Shouldn't it stop reading when EOF is reached?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,677
    > while ((n = fread(buf, 1, 512, src)) > 0)
    > if (fwrite(buf, 1, 512, dst) != n)

    Pass n to fwrite, not 512

    You want to write the number of bytes you read.


    > while ((n = fread(buf, 512, 1, src))
    Yeah, what you're saying here is I want to read a single record of 512 bytes.
    This is an all-or-nothing deal. You either get all 512 bytes or you get nothing.

    > size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    Parameter 2 is the size of each data unit in the file.
    Parameter 3 is how many of them you want to read.

    Oh, and I had to change the topic title slightly.
    The board doesn't like fread/fwrite in topic titles.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2024
    Posts
    20
    Quote Originally Posted by Salem View Post
    > while ((n = fread(buf, 1, 512, src)) > 0)
    > if (fwrite(buf, 1, 512, dst) != n)

    Pass n to fwrite, not 512

    You want to write the number of bytes you read.
    Oh my, this was so simple, yet I couldn't figure out what was going on...


    Quote Originally Posted by Salem View Post
    Oh, and I had to change the topic title slightly.
    The board doesn't like fread/fwrite in topic titles.
    OK, I'll keep this in mind in the future.

    Thanks for your help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Copying contents of file to another
    By Omar Sharaki in forum C Programming
    Replies: 2
    Last Post: 05-06-2016, 12:13 PM
  2. Replies: 3
    Last Post: 03-13-2013, 07:10 PM
  3. Problem while copying the contents of file to a buffer.
    By chibi.coder in forum C Programming
    Replies: 8
    Last Post: 04-01-2012, 08:51 AM
  4. Replies: 16
    Last Post: 11-09-2011, 02:56 PM
  5. read contents of a text file into a struct
    By lemonwaffles in forum C++ Programming
    Replies: 2
    Last Post: 08-03-2009, 02:20 PM

Tags for this Thread