Страница 2 из 2

Re: Копирование файлов на С

Добавлено: 11 янв 2016, 16:16
Romeo
Skwoogey писал(а):Ладно. С переписанными файлами фишку понял, но недописанные все еще есть. причем, чем я больше делаю строку, тем недобор больше.
Выложи окончательный код. Может ещё что-то неверно.

Re: Копирование файлов на С

Добавлено: 11 янв 2016, 16:23
Skwoogey
Romeo писал(а):Выложи окончательный код. Может ещё что-то неверно.

Код: Выделить всё

#include <stdio.h>
#include <dirent.h>
#include <utime.h>
#include <time.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>

char d_one[100] = "C:\\sample1";
char d_two[100] = "C:\\sample2";

void name_maker(char *out,char *in,int mode)
{
	if(mode == 1)
	{
		strcpy(out,d_one);
		strcat(out,"\\");
		strcat(out,in);
	}
	else
	{
		strcpy(out,d_two);
		strcat(out,"\\");
		strcat(out,in);
	}
}
void copyfile(char *file,int mode)
{
	FILE *fp1,*fp2;
	char bak[100];
	name_maker(bak,file,mode);
	puts(bak);
	if((fp1 = fopen(bak, "rb")) == NULL)
	puts("net1");
	char file_nm[100];
	name_maker(file_nm,file,-mode);
	puts(file_nm);
	if((fp2 = fopen(file_nm,"w")) == NULL)
	puts("net2");
	char k[10000];
	size_t rc;
	
	while((rc = fread(k, sizeof(k), 1, fp1)) != 0)
	{
		fwrite(k, sizeof(k), rc, fp2);;
		puts("cycle");
	}
	puts("done");
	fclose(fp1);
	fclose(fp2);
}
int main()
{
	//copyfile("kek.djvu",1);
	//getchar();
	int test;
	DIR *dir1,*dir2;
	char d_one[100] = "C:\\sample1";
	char d_two[100] = "C:\\sample2";
	dir1 = opendir(d_one);
	dir2 = opendir(d_two);
	struct dirent *f1,*f2;
	f1 = readdir(dir1);
	f2 = readdir(dir2);
	int i;
	for(i=0;i<2;i++)
	{
	f1 = readdir(dir1);
	}
	for(i=0;i<2;i++)
	{
	f2 = readdir(dir2);
	}
	if((f1 != NULL) && (f2 != NULL))
	{
	while(1)
	{
		puts(f1->d_name);
		puts(f2->d_name);
		if(strcmp(f1->d_name,f2->d_name) == -1)
		{
			copyfile(f1->d_name,1);
			if((f1 = readdir(dir1)) == NULL)
				break;
			continue;
		}
		if(strcmp(f1->d_name,f2->d_name) == 1)
		{
			copyfile(f2->d_name,-1);
			if((f2 = readdir(dir2)) == NULL)
				break;
			continue;
		}
		char file1[100],file2[100];
		name_maker(file1,f1->d_name,1);
		puts(file1);
		name_maker(file2,f2->d_name,-1);
		puts(file2);
		
		struct stat ff1,ff2;
		test = stat(file1,&ff1);
		printf("%d\n",test);
		test = stat(file2,&ff2);
		printf("%d\n",test);
		if(difftime(ff1.st_mtime,ff2.st_mtime) > 0)
		{
			puts("1");
			getchar();
			unlink(file2);
			copyfile(f1->d_name,1);
			if((f1 = readdir(dir1)) == NULL)
				break;
			if((f2 = readdir(dir2)) == NULL)
				break;
			continue;
		}
		if(difftime(ff1.st_mtime,ff2.st_mtime) < 0)
		{
			puts("2");
			getchar();
			unlink(file1);
			copyfile(f2->d_name,-1);
			if((f1 = readdir(dir1)) == NULL)
				break;
			if((f2 = readdir(dir2)) == NULL)
				break;
			continue;
		}
		if((f1 = readdir(dir1)) == NULL)
			break;
		if((f2 = readdir(dir2)) == NULL)
			break;
	}
	}
	while(f2 != NULL)
	{
		copyfile(f2->d_name,-1);
		f2 = readdir(dir2);
	}
	while(f1 != NULL)
	{
		copyfile(f1->d_name,1);
		f1 = readdir(dir1);
	}
	return 0;
}
Код должен синхронизировать две директории. Случай "папка в папке" я еще не рассматривал. Пока пытаюсь заставить это работать.

Различные puts() у меня для отладки.

Re: Копирование файлов на С

Добавлено: 11 янв 2016, 16:48
Romeo
У тебя вот так:

Код: Выделить всё

fwrite(k, sizeof(k), rc, fp2);;
А теперь сравни с тем куском кода, который я два сообщения назад дал.

Третий параметр - это сколько раз нужно записать в файл весь буфер...

Re: Копирование файлов на С

Добавлено: 11 янв 2016, 17:29
Skwoogey
Теперь он записывает в файл несколько килобайт и успокаивается. а в очень маленькие файлы вообще ничего не пишет

Код: Выделить всё

	char k[1000];
	size_t rc;
	
	while((rc = fread(&k, sizeof(k), 1, fp1)) != 0)
	{
		fwrite(&k, rc, 1, fp2);;
		puts("ch");
	}
Простите если докучаю.

Re: Копирование файлов на С

Добавлено: 11 янв 2016, 19:23
Absurd
Паапробуй пааменять полярность

Код: Выделить всё

fread(&k, 1, sizeof(k), fp1);
Кстати, на собеседованиях обожают сыпать с порядком этих параметров.

Re: Копирование файлов на С

Добавлено: 11 янв 2016, 19:27
Skwoogey
Absurd писал(а):Паапробуй пааменять полярность

Код: Выделить всё

fread(&k, 1, sizeof(k), fp1);
Кстати, на собеседованиях обожают сыпать с порядком этих параметров.

Работает! Но как вы догадались?

Re: Копирование файлов на С

Добавлено: 11 янв 2016, 19:48
Absurd
Работает! Но как вы догадались?
Однажды обидно запоролся на собеседовании в хорошую компанию с этим вонючим гнойным fread.

PS: В fwrite для симметрии тоже поменять наверно надо.

Re: Копирование файлов на С

Добавлено: 11 янв 2016, 22:41
Romeo
Да никак он не догадался. Просто внимательно прочёл мануал :)
size
Size, in bytes, of each element to be read.
size_t is an unsigned integral type.

count
Number of elements, each one with a size of size bytes.
size_t is an unsigned integral type.

Return Value
The total number of elements successfully read is returned.
Return value - это number of elements, а не number of bytes. В этом была хитрость :)

Само собой, в fwrite то же самое.

Re: Копирование файлов на С

Добавлено: 11 янв 2016, 23:42
Skwoogey
Я смотрел вот здесь. Мне казалось, что это первоисточник, и там не наврут, Хотя там сначала размер а потом каунтер. Тогда такой вопрос: Где можно спокойно найти большинство информации, чтобы она была валидная?

хотя может он записывает кучу чаров в массив, а sizeof() в данном случае возвращает кол-во элементов массива. Тип ведь по сути тот же. Если это так, то я вроде наконец-то понял принцип их работы...

А передача по 1 байту позволяет нам сохранить точность...

И тогда получается, что информация там правильная...

Я идиот. Простите, что отнял время.

Re: Копирование файлов на С

Добавлено: 12 янв 2016, 00:13
Romeo
Всё именно так, как ты понял.

Мы указываем, что у одного элемента размер 1, а потом говорим сколько таких элементов прочесть. Возвращает функция количество элементов, которые прочла. В таком режиме получится прочесть всё до последнего байта и ничего не потерять.

Если поменять местами значения, то получается мы говорим, что один элемент имеет размер 10000 байт, и читать нужно по одному такому элементу. Тогда, если остаток данных в конце файла не уляжется точно по размеру буфера, то будет утерян, так как fread вернёт 0, при попытке его прочитать, ведь элемент теперь имеет размер 10000, а в файле не осталось данных, чтобы вычитать элемент целиком.

Ничего страшного, что отнял время. Обращайся ещё, если будет нужна помощь.

P.S. А мануал на fread, кстати, идентичен тому, на который давал ссылку я. Вообще ресурс gnu.org вполне серьёзный, ему можно доверять, хотя я больше предпочитаю cppreference.com и MSDN.