1

I'm just getting started into file I/O and am trying to build a function that will simply copy a file to destination.

This program compiles however an empty file is created and nothing is copied. Any advice?

#include <stdio.h>

int copy_file(char FileSource[], char FileDestination[]) {
    char content;

    FILE *inputf = fopen(FileSource, "r");
    FILE *outputf = fopen(FileDestination, "w");

    if (inputf == NULL)
        ;
    printf("Error: File could not be read \n");
    return;

    while ((content = getc(inputf)) != EOF) putc(content, inputf);

    fclose(outputf);
    fclose(inputf);
    printf("Your file was successfully copied");

    return 0;
}


int main() {
    char inputname[100];
    char outputname[100];

    printf("Please enter input file name: \n");
    scanf("%s", &inputname);
    printf("Please write output file name: \n");
    scanf("%s", &outputname);

    copy_file(inputname, outputname);

    return 0;
}
Vikas
  • 11,859
  • 7
  • 45
  • 69
franx
  • 57
  • 6

5 Answers5

1

There are few bugs in the code you mentioned. These two below statement

scanf("%s", &inputname);
scanf("%s", &outputname);

Are wrong as inputname and outputname are char array and array name itself address so you no need to give &inputname to scanf(). For e.g

scanf("%s",inputname);
scanf("%s",outputname);

Also ; at the end of if statement is not serving correct purpose as you expected.

This

if(inputf == NULL);

Should be

if(inputf == NULL){ 
     /*error handling */ 
}

As pointed by other, getc() returns int not char. From the manual page of getc()

int getc(FILE *stream);

And this

 putc(content, inputf);

Change to

putc(content, outputf); /* write the data into outputf */
Achal
  • 11,821
  • 2
  • 15
  • 37
0

Your line :

putc(content, inputf);

needs to change to

putc(content, outputf);
auburg
  • 1,373
  • 2
  • 12
  • 22
  • Thank you. It did work. However when I tried doing it with fprintf and fscanf it didnt work. Besides could anyone tell me the difference betwen fgets and gets and fputs and puts? – franx Jun 14 '18 at 10:10
  • See https://stackoverflow.com/questions/3302255/c-scanf-vs-gets-vs-fgets – auburg Jun 14 '18 at 10:14
0

This code has a lot of problems:

if(inputf == NULL); 
    printf("Error: File could not be read \n");
    return;

It is the equivalent of

if(inputf == NULL)
{
    ;
} 
printf("Error: File could not be read \n");
return;

You have a stray ; that terminates you if statement, and whitespace doesn't matter much at all with C.

So your if statement does nothing, and your code will always emit the "Error: File could not be read" message and return without doing anything else.

What you probably want:

if(inputf == NULL)
{
    printf("Error: File could not be read \n");
    return;
}

This is a perfect example of why a lot of C programmers always use braces after if statements. ALWAYS.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
0

There are multiple problems in your code:

  • content must be declared as int: getc() returns an int with the value of the byte read from the file or the special negative value EOF at end of file. Storing that to a char variable loses information, making the test for EOF either ambiguous (if char is signed) or always false (if char is unsigned by default).
  • you should pass outputf to putc.
  • you should return from the copy_file function if fopen fails to open either file.
  • you should pass the maximum number of characters to read for the filenames
  • you should check the return value of scanf() to avoid undefined behavior on invalid input.

Here is a corrected version:

#include <stdio.h>

int copy_file(const char *FileSource, const char *FileDestination) {
    int content;
    FILE *inputf, *outputf;

    if ((inputf = fopen(FileSource, "r")) == NULL) {
        printf("Error: cannot open input file %s\n", FileSource);
        return -1;
    }
    if ((outputf = fopen(FileDestination, "w")) == NULL) {
        printf("Error: cannot open output file %s\n", FileDestination);
        fclose(inputf);
        return -1;
    }

    while ((content = getc(inputf)) != EOF)
        putc(content, inputf);

    fclose(outputf);
    fclose(inputf);
    printf("Your file was successfully copied");

    return 0;
}

int main() {
    char inputname[100];
    char outputname[100];

    printf("Please enter input file name: \n");
    if (scanf("%99s", inputname) != 1)
        return 1;
    printf("Please write output file name: \n");
    if (scanf("%99s", &outputname) != 1)
        return 1;

    copy_file(inputname, outputname);
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
0

Use sendfile() is more simple and efficient for copying file. You can view more detail about sendfile() by man sendfile.

#include <stdio.h>
#include <string.h>
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
    if (argc < 3)
    {
        printf("Usage: %s <srcfile> <dst_file>\n", argv[0]);
        return 1;
    }

    char *src_file = argv[1];
    char *dst_file = argv[2];
    int src;
    int dst;
    ssize_t size;
    struct stat stat_buf;

    if ((src = open(src_file, O_RDONLY)) < 0)
    {
        printf("Can not open %s\n", src_file);
        return -1;
    }

    if (fstat(src, &stat_buf) < 0)
    {
        printf("Can stat %s\n", src_file);
        close(src);
        return -2;
    }

    if ((dst = open(dst_file, O_CREAT|O_WRONLY, stat_buf.st_mode)) < 0)
    {
        printf("Can not open %s\n", dst_file);
        return -1;
    }

    if ((size = sendfile(dst, src, NULL, stat_buf.st_size)) < 0)
    {
        printf("Fail to copy file, size: %ld\n", size);
    }
    else
    {
        printf("Success, size: %ld\n", size);
    }

    close(src);
    close(dst);
    return 0;
}
Joy Allen
  • 402
  • 3
  • 8