#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void filecpy(FILE *stream_from, FILE *stream_to);

// Буфера для файлов

char buf1[BUFSIZ * 10];
char buf2[BUFSIZ * 10];

void main(int argc, char *argv[]) {

	 time_t start, end;
	 FILE *stream_from, *stream_to;


	 if(argc < 3) {
		  printf("Задайте имена файлов!\n");
		  exit(-1);
	 }

// Открываем файлы и используем для копирования
// буфер стандартного размера

	 if((stream_from = fopen(argv[1], "rt")) == NULL) {
		  printf("Задайте имя входного файла!\n");
		  exit(-1);
	 }
	 stream_to = fopen(argv[2], "wt+");

// Определяем время начала копирования

	 start = clock();

// Выполняем копирование файла

	 filecpy(stream_from,stream_to);

// Определяем время завершения копирования

	 end = clock();

// Выводим время копирования при использовании
// буферов стандартного размера

	 printf("Время копирования: %5.1f Размер буфера, байтов: %d\n",
				 ((float)end - start) / CLK_TCK, BUFSIZ);


// Задаем свой буфер большего размера

	 if((stream_from = fopen(argv[1], "rt")) == NULL) exit(-1);
	 stream_to = fopen(argv[2], "wt+");

// Устанавливаем буфера как для входного,
// так и для выходного файлов

	 setvbuf(stream_from, buf1, _IOFBF, sizeof(buf1));
	 setvbuf(stream_to,   buf2, _IOFBF, sizeof(buf2));

// Копируем файл и измеряем продолжительность
// копирования

	 start = clock();
	 filecpy(stream_from,stream_to);
	 end = clock();

	 printf("Время копирования: %5.1f Размер буфера: %d\n",
				 ((float)end - start) / CLK_TCK, BUFSIZ * 10);

// Копируем без использования буферизации

	 if((stream_from = fopen(argv[1], "rt")) == NULL) exit(-1);
	 stream_to = fopen(argv[2], "wt+");

	 setvbuf(stream_from, NULL, _IONBF, 0);
	 setvbuf(stream_to,   NULL, _IONBF, 0);

	 start = clock();
	 filecpy(stream_from,stream_to);
	 end = clock();

	 printf("Время копирования: %5.1f Буферизация не используется\n",
				 ((float)end - start) / CLK_TCK);

	 exit(0);
}

// Функция для копирования файлов

void filecpy(FILE *stream_from, FILE *stream_to) {

	 char linebuf[256];

// Цикл копирования. Условие выхода из цикла -
// конец входного файла

	 while(!feof(stream_from)) {

// Читаем в буфер linebuf одну строку

		  if(fgets(linebuf, 255, stream_from) == NULL) break;

// Записываем содержимое буфера linebuf
// в выходной файл

		  if(fputs(linebuf, stream_to) != 0) break;
	 }

// Закрываем входной и выходной файлы

	 fclose(stream_from);
	 fclose(stream_to);

}

