You need to realize that when you fgets the filename, you are reading an input line that includes (depending upon operating system) a linefeed, carriage return, or both. So you need a convenient way to remove these extraneous character(s).
Borrowing an idea from perl, et al, I like chomp(), which removes the '\n' and '\r' from the end of the line.
You also need to be careful with your filenames versus file handles, the fputc on the filename rather than the file handle.
And char[20] is rather small for a filename, try 200+; and you might find that "w+" will create the output file when it doesn't exist; and use sizeof(variable) for fgets size, rather than hardcoded sizes.
This works,
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* chomp(char* p)
{
int len;
if(!p) return(p);
if( (len=strlen(p))<=0 ) return(p);
if( p[len-1] == '\n' ) { p[--len] = '\0'; }
if( p[len-1] == '\r' ) { p[--len] = '\0'; }
return(p);
}
int main()
{
/* Create Usable Variables */
FILE *src_fh, *dst_fh;
char src_fn[256+1], dst_fn[256+1];
/* Retrieve Source File Name From User */
printf("Enter Source File Name:\n");
fgets(src_fn, sizeof(src_fn), stdin); chomp(src_fn);
/* Attempt Opening Source File For Reading */
if( (src_fh = fopen(src_fn, "r")) == NULL )
{
printf("ERROR: Source File %s Failed To Open...\n",src_fn);
return(-1);
}
/* Retrieve Destination File Name From User */
printf("Enter Destination File Name:\n");
fgets(dst_fn, sizeof(dst_fn), stdin); chomp(dst_fn);
/* Attempt Opening Destination File For Writing */
if( (dst_fh = fopen(dst_fn, "w+")) == NULL )
{
fclose(src_fh);
printf("ERROR: Destination File %s Failed To Open...\n",dst_fn);
return(-2);
}
int ch;
/* Copy Source File Contents Into Destination File */
while( (ch = fgetc(src_fh)) != EOF )
{
fputc(ch, dst_fh);
}
/* Close Files On Success */
fclose(src_fh);
fclose(dst_fh);
return 0;
}