View Single Post
Old 09-26-2005, 05:49 AM   #3 (permalink)
Locutus
Registered User
 
Join Date: Aug 2005
Posts: 20
Locutus is on a distinguished road
Quote:
Originally Posted by pre_wreck
/* Get the source and destination names. */

printf("\nEnter source file: ");
gets(source);
printf("\nEnter destination file: ");
gets(destination);
Using gets() is a buffer overflow waiting to happen. If you really want to do things this way, at least use fgets(). Also, arbitrary limits on the size of your input/output filenames (or actually buffers / arrays in general) will pretty much always cause you problems later on.

The "proper" way to handle stuff like this for these kind of programs is to either use stdin & stdout to read and write, use command line arguments, or do both. ie, my_prog < infile > outfile, or my_prog infile -o outfile, etc.

Quote:
Originally Posted by pre_wreck
if ( file_copy( source, destination ) == 0 )
puts("Copy operation successful");
else
fprintf(stderr, "Error during copy operation");
Any particular reason you're using puts() when successful and fprintf to stderr on failure? In general if an operation succeeds you give no output, if it fails you output an error. If you do output status info, send it to stderr. Also, you probably want to add a newline at the end of your output .

redhead wrote a possible solution already, but since I was bored :
Code:
#include <stdio.h>
#include <stdlib.h>

#define BUFF_SIZE	4096

int file_copy(FILE *fin, FILE *fout)
{
	enum STATE {
		STATE_SPACE,
		STATE_NEWLINE,
		STATE_DEFAULT
	} state = STATE_NEWLINE;

	size_t num_read = 0, num_write = 0;
	char *buff = 0, *ptr = 0;
	size_t i = 0;

	buff = malloc(BUFF_SIZE);
	if (!buff) return -1;

	while (!feof(fin))
	{
		num_read = fread(buff, sizeof(char), BUFF_SIZE, fin);
		if (!num_read) 
		{
			fprintf(stderr, "Error in read\n");
			free(buff);
			return -1;
		}
		
		for (i = 0, ptr = buff; i < num_read; i++)
		{
			switch(buff[i])
			{
				//case '\t':		//Uncomment to strip tabs as well
				case ' ':
					if (state == STATE_NEWLINE) break;
					state = STATE_SPACE;
					break;
				
				case '\n':
					*ptr++ = buff[i];
					state = STATE_NEWLINE;
					break;

				default:
					if (state == STATE_SPACE) *ptr++ = ' ';
					*ptr++ = buff[i];
					state = STATE_DEFAULT;
					break;
			}
		}
		
		if (!(num_write = ptr - buff)) continue;	//Nothing to write

		if (!fwrite(buff, sizeof(char), num_write, fout))
		{
			fprintf(stderr, "Error in write\n");
			free(buff);
			return -1;
		}
	}

	free(buff);

	return 0;
}

int main()
{
	if (file_copy( stdin, stdout) != 0)
	{
		fprintf(stderr, "Error during copy operation\n");
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
Locutus is offline   Reply With Quote