Перейти к содержимому

Фото
- - - - -

C++


  • Вы не можете создать новую тему
  • Please log in to reply
14 ответов в этой теме

#1 Tiptreth

Tiptreth
  • Пользователь
  • 36 сообщений
  • Откуда:Tokyo, Japan

Отправлено 05 Ноябрь 2006 - 11:00

Надо вот тут консольное приложение ввиде Адресной книги сделать.
Написал вот метод по удалению записи из файла по имение и фамилии. только он почемуто удаляет все записи, вообщем очищает файл. В чём может быть проблема, не подскажете?
заранее спасибо.
void remove_users()
{
	FILE *ftmp;
	User user,next;

	ftmp=fopen("tmp.db","w+b");

	if(!ftmp)
	{
		perror("Tmp_file_error");
		return;
	}

	printf("\nFirstname: ");
	scanf("%s",user.firstname);
	printf("\nSecondname: ");
	scanf("%s",user.secondname);
	if(db_open())
	{
		fseek(fdb,0,SEEK_SET);
		while(fread(&next,sizeof(User),1,fdb))
		{
			if((strlen(user.firstname)!= strlen(next.firstname))
				&& !strcmp(user.firstname, next.firstname)&& !strcmp(user.secondname,next.secondname))
			{
				fwrite(&next,sizeof(User),1,ftmp);
			}
		}
		//db_close();

		//fail zakrivaesja i otkrivaetsja
		freopen(DBNAME,"w+b",fdb);
		if(fdb)
		{
			fseek(ftmp,0,SEEK_SET);
			while(fread(&next,sizeof(User),1,ftmp))
			{
				fwrite(&next,sizeof(User),1,fdb);
			}
			fclose(ftmp);
		}
		else
		{
			perror("File_error");
		}
	}
}

  • 0

#2 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 05 Ноябрь 2006 - 12:20

> ftmp=fopen("tmp.db","w+b");
опция "w+" удаляет содержимое файла
  • 0
int main(void)

#3 Tiptreth

Tiptreth
  • Пользователь
  • 36 сообщений
  • Откуда:Tokyo, Japan

Отправлено 05 Ноябрь 2006 - 12:27

это я знаю, но tmp.db - это временный файл, он сохраняет строчку которая будет удалена из главной базы данных файла users.db, известный в коде как DBNAME.
  • 0

#4 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 05 Ноябрь 2006 - 12:38

> freopen(DBNAME,"w+b",fdb);
та же причина
  • 0
int main(void)

#5 Tiptreth

Tiptreth
  • Пользователь
  • 36 сообщений
  • Откуда:Tokyo, Japan

Отправлено 05 Ноябрь 2006 - 12:43

а я только заметил )
а что должно быть тогда? wb?

в файл усерс.дб записываются сторки с именем,фамилией,адресом и телефоном.
суть метода удаления, нужно спросить имя и фамилию, найти эту записть в усерс.дб и удалить всю строчку.
но я решил, сначала записать всю сторчку во временный файл, а потом её найти в главной и удалить, может я неправильно подошёл?
да и плюс и в си не силён )

Сообщение изменено: Tiptreth (05 Ноябрь 2006 - 12:45 )

  • 0

#6 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 05 Ноябрь 2006 - 12:49

в твоем случае "ab" ili "a+b"
  • 0
int main(void)

#7 Tiptreth

Tiptreth
  • Пользователь
  • 36 сообщений
  • Откуда:Tokyo, Japan

Отправлено 05 Ноябрь 2006 - 12:52

теперь он файл не очищат, но и не удаляет нужную записть =/
  • 0

#8 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 05 Ноябрь 2006 - 13:09

ну сейчас у тебя почти чистый C, а не C++ :)
а алгоритм такой:
имеется файл со строчками данных. нужно удалить 1 запись.
есть минимум 2 возможности

1) открываешь ишодный файл. открываешь темп-файл. считываешь из ишодного строку и сравниваешь с той, которую надо удалить. если не совпадают, то пишешь в темп-файл строку из исходного. совпадают - не пишешь. так до конца файла с данными. потом удаляешь старый файл и переименовываешь темп в исходный.
2) открываешь исходный файл как "r". считываешь весь исходный файл в память, закрываешь, открываешь как "w" и пишешь из памяти только то, что не совпадает с искомой строчкой


if((strlen(user.firstname)!= strlen(next.firstname))
				&& !strcmp(user.firstname, next.firstname)&& !strcmp(user.secondname,next.secondname))
так у тебя никогда не найдет ничего, правильно будет
if((strlen(user.firstname) == strlen(next.firstname))
				&& !strcmp(user.firstname, next.firstname)&& !strcmp(user.secondname,next.secondname))
или вобще без проверки strlen
  • 0
int main(void)

#9 Tiptreth

Tiptreth
  • Пользователь
  • 36 сообщений
  • Откуда:Tokyo, Japan

Отправлено 05 Ноябрь 2006 - 13:18

да я потом написал, что эт си )
пасиба за алгоритмики.
ну сначала мне надо найти имя и фамилию, если зпаись найдена прога спрашивает, типа remove ‘вся пупкин’? (y/n) n>.
тогда уже читать в память и из памяти записывать всё, кроме этой строки.
а как например записать, исключая данную запись? если есть время можешь пример в пару строк чиркануть :)

if((strlen(user.firstname) == strlen(next.firstname))
				&& !strcmp(user.firstname, next.firstname)&& !strcmp(user.secondname,next.secondname))

накасячил )
теперь он добавляет найденную запись
  • 0

#10 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 05 Ноябрь 2006 - 13:56

ну что то наподобе этого:
#include <stdio.h>
#include <string.h>

int found(const char *s, FILE *fp)
{
	char t[BUFSIZ];
	size_t i = 1;
	while (fgets(t, sizeof t, fp) != NULL)
	{
	  if (!strncmp(s, t, strlen(s)))
		return i;
	  i++;
	}
	   
	return 0;
}

FILE * rem_at_pos(const char *n, const char * fn, FILE *fp, size_t pos)
{
	char *tf = "temp.tmp";
	FILE *tp = fopen(tf, "w");
	char t[BUFSIZ];
	size_t i = 1;
	
	while (fgets(t, sizeof t, fp) != NULL)
	  if (i++ != pos)
		fputs(t, tp);
		
	fclose(fp);
	fclose(tp);
	remove(fn);
	rename(tf, fn);
	
	return (fp = fopen(fn, "r"));
}

int
main(void)
{

	FILE *f, *t;
	int k;
	
	const char nd[] = "a";
	const char fn[] = "n.txt";
	
	f = fopen(fn, "r");
	
	if ((k = found(nd, f)))
	{   // found at line k
		//ask delete? y/n
		
		rewind(f); 
		f = rem_at_pos(nd, fn, f, k);
	}
	

	
   // while(getchar());
	return 0;
}


  • 0
int main(void)

#11 Tiptreth

Tiptreth
  • Пользователь
  • 36 сообщений
  • Откуда:Tokyo, Japan

Отправлено 05 Ноябрь 2006 - 15:53

спасибо большое, я сначала попрпбую добить свой метод, если не получится то сделаю твоим способом.
низнаешь почему у меня не удаляет запись, а наоборот добавляет? :)
плюс я там поставил вопросы, типо если надо удалить всё, пишешь алл, и на удаление вопрос. только они не работают.
вроде правильно написано, покрайней мере в C# срабтало бы.

void remove_users()
{
	FILE *ftmp;
	User user,next;
	char question[16];
	char status;

	ftmp=fopen("tmp.db","w+b");

	if(!ftmp)
	{
		perror("Tmp_file_error");
		return;
	}

	printf("\nIf u want delete all data, please type 'all' in Firstname line!");
	printf("\nFirstname: ");
	scanf("%s",user.firstname);
	if(user.firstname=="all")
	{
		printf("zomg");
		//udalenie fajla
	}
	else
	{
	printf("\nSecondname: ");
	scanf("%s",user.secondname);
	if(db_open())
	{
		fseek(fdb,0,SEEK_SET);
		while(fread(&next,sizeof(User),1,fdb))
		{
			if((strlen(user.firstname)== strlen(next.firstname)) && (strlen(user.secondname)== strlen(next.secondname))
				&& !strcmp(user.firstname, next.firstname)&& !strcmp(user.secondname,next.secondname))
			{
				printf("\nremove %s, %s (y/n)?",user.firstname,user.secondname);
				scanf("%s",question);
				if(question=="y")
				{
				fwrite(&next,sizeof(User),1,ftmp);
				}
				else
					break;
			}
		}
		//db_close();

		//fail zakrivaesja i otkrivaetsja
		freopen(DBNAME,"a+b",fdb);
		if(fdb)
		{
			fseek(ftmp,0,SEEK_SET);
			while(fread(&next,sizeof(User),1,ftmp))
			{
				fwrite(&next,sizeof(User),1,fdb);
			}
			fclose(ftmp);
		}
		else
		{
			perror("File_error");
		}
	}
}
}

  • 0

#12 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 05 Ноябрь 2006 - 20:47

> if(user.firstname=="all")
что такое user.firstname? если массив char, то это неправильно, используй strcmp.
добавляет, потому что ты открываешь файл как "a+b", то есть read+append+binary. я тогда написал "a+b" потому что думал проблема только в том, что у тебя стирается файл
  • 0
int main(void)

#13 Tiptreth

Tiptreth
  • Пользователь
  • 36 сообщений
  • Откуда:Tokyo, Japan

Отправлено 05 Ноябрь 2006 - 20:58

user.firstname
у меня ест структура user, а firstname обозначен там как char username[64];
хочу проверит, если я пишу "алл", то он удаляет все записи.
так как решит проблему с а+б? если а+б, то он добавляет, если w+b, он удаляет все записи =/
  • 0

#14 V^v

V^v
  • Пользователь
  • 316 сообщений

Отправлено 05 Ноябрь 2006 - 21:26

тогда сравнивать надо strcmp(user.firstname, "all");
решить проблему так как я написал выше. чтобы удалить строчку нужно просмотреть весь файл и сравнить все строчки
  • 0
int main(void)

#15 witeX

witeX
  • Новобранец
  • 4 сообщений

Отправлено 23 Ноябрь 2006 - 02:09

С++ реально через if(x == 'c')
только символы сравнивать!
А что бы строку то надо strcmp сравнивать! подругому ни как! ну можешь загнать цикл! проверить по символу!=)
  • 0
Я не волшебник, я только учусь!