operacje we/wy na plikach binarnych

0

Mam za zadanie napisac kod ktory wczytuje z pliku w trybie tekstowym dane do sktruktury nastepnie blyskawicznie zapisuje te dane do pliku w trybie binarnym poczym wczytuje te z pliku w trybie binarnym do listy dwukierukowej a nastepnie liste zapisuje w 2 plikach tekstowych w 1 zgodnie kolejnoscia w 2 odwrotnie tj 1 2 3 4// 4 3 2 1
wszystko dziala tylko jest jeden problem w momencie wczytywania do listy z pliku binarnego wczytywana zostaje zawsze JEDNA porcja za duzo danych do struktury czyli tzw smieci z czego to moze wynikac ? oto kod

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

struct osoba{
	char imie[20];
	char nazwisko[30];
	int wiek;
	osoba *nast;
	osoba *poprz;
};

void odczyt_t(FILE *t_odczyt, FILE *b_zapisb)
{
	osoba *os_odczyt_t;
	os_odczyt_t=(osoba *)malloc(sizeof(osoba));
	while(!(feof(t_odczyt)))
	{
		fscanf(t_odczyt,"%s%s%d", os_odczyt_t->imie, os_odczyt_t->nazwisko, &os_odczyt_t->wiek);
		printf("%s %s %d\n", os_odczyt_t->imie, os_odczyt_t->nazwisko, os_odczyt_t->wiek);
		fwrite(os_odczyt_t->imie, sizeof(os_odczyt_t->imie), 1, b_zapisb);
		fwrite(os_odczyt_t->nazwisko, sizeof(os_odczyt_t->nazwisko), 1, b_zapisb);
		fwrite(&os_odczyt_t->wiek, sizeof(os_odczyt_t->wiek), 1, b_zapisb);
	}
	free(os_odczyt_t);
	printf("\n\n\n\n");
}

osoba *last;

osoba * odczyt_b(FILE *b_odczytb)
{
	osoba *glowa,*ogon,*stary;
	glowa=NULL;
	while(!(feof(b_odczytb)))
	{
		if(glowa==NULL)
		{
			glowa=ogon=(osoba *)malloc(sizeof(osoba));
			glowa->poprz=NULL;
		}
		else
		{
			ogon->nast=(osoba *)malloc(sizeof(osoba));
			ogon=ogon->nast;
			ogon->poprz=stary;
		}
		ogon->nast=NULL;
		stary=ogon;
		last=stary;
		fread(ogon->imie, sizeof(ogon->imie), 1, b_odczytb);
		fread(ogon->nazwisko, sizeof(ogon->nazwisko), 1, b_odczytb);
		fread(&ogon->wiek, sizeof(ogon->wiek), 1, b_odczytb);
		printf("%s %s %d\n", ogon->imie, ogon->nazwisko, ogon->wiek);
	}
	return glowa;
}

void zg_zapis(osoba *glowa)
{
	FILE *zapis;
	zapis=fopen("zgodnie.txt","w");
	while(glowa!=NULL)
	{
		fprintf(zapis, "%s %s %d\n", glowa->imie, glowa->nazwisko, glowa->wiek);
		glowa=glowa->nast;
		zg_zapis(glowa);
	}
	fclose(zapis);
	return ;
}

void od_zapis(osoba *last)
{
	FILE *zapis;
	zapis=fopen("odwrotnie.txt","w");
	while(last!=NULL)
	{
		fprintf(zapis, "%s %s %d\n", last->imie, last->nazwisko, last->wiek);
		last=last->poprz;
		od_zapis(last);
	}
	fclose(zapis);
	return ;
}




int main(void)
{

	osoba *glowa;
	char odczyt[256];
	char zapisb[256];
	printf("podaj nazwy plikow do oczytu i zapisu danych\n");
	scanf("%s", odczyt);
	scanf("%s", zapisb);
	FILE *t_odczyt,*b_zapisb;
	t_odczyt=fopen(odczyt,"r");
	b_zapisb=fopen(zapisb,"wb");
	odczyt_t(t_odczyt, b_zapisb);
	fclose(t_odczyt);
	fclose(b_zapisb);
	b_zapisb=fopen(zapisb,"rb");
	glowa=odczyt_b(b_zapisb);
	zg_zapis(glowa);
	od_zapis(last);
	while(last)
	{
		glowa=last;
		last=last->poprz;
		free(glowa);
	}
	return 0;
}
0

Wynika to z tego że źle tworzysz listę.

0

W takim razie jak powinna byc tworzona

0

No każdym dodaniu elementu do listy.
zmienna glowa - powinna wskazywać na pierwszy dodany element.
zmienna last - powinna wskazywać na ostatni dodany element.
Każdy element w składowej nast powinien wskazywać na następny (oprócz ostatniego, tam powinien wskazywać na NULL)
Każdy element w składowej poprz powinien wskazywać na poprzedni (oprócz pierwszego, tam powinien wskazywać na NULL)
Twoja funkcja dodająca elementy do listy powinna spełniać powyższe kryteria, oprócz tego nie powinna mazać po pamięci.

Przepraszam, przejrzałem się temu jeszcze raz i jednak funkcja dodaje poprawnie, z tym że w tak pokręcony sposób że nie sposób się połapać.
Problem masz gdzie indziej:
Po poprawnym odczycie ostatniego rekordu feof() jeszcze nie zwróci prawdy.
Zwróci prawdę dopiero kiedy spróbujesz odczytać kolejny rekord.
Powinieneś najpierw spróbować wczytać do jakichś danych lokalnych, potem sprawdzić czy nie wystąpił feof() i ewentualnie wyjść z pętli.
Dopiero jeżeli nie wystąpił eof() dodawać te dane do listy.

Właściwie to samo dotyczy plików tekstowych, czyli eof() masz dopiero kiedy "próbujesz" wyjść poza koniec a nie wtedy gdy osiągnąłeś ten koniec.

0

tak wlasnie myslalem jednakze przy plikach tekstowych najczesciej problemem jest enter na koncu wtedy wystarczy go usunac jednakze tutaj nie bylo zadnego entera wiec zastosowalem takie wyjscie

fgetpos(b_odczytb, &poz);
		if(getc(b_odczytb)==EOF)
			return glowa;
		else
			fsetpos(b_odczytb, &poz);

1 użytkowników online, w tym zalogowanych: 0, gości: 1