Cześć,
Mam do popełnienia taki oto program:
Zdefiniować typ strukturalny
typedef struct tosoba { char naz[20]; long id; }.
Opracować następujące funkcje obsługujące plik złożony ze zmiennych strukturalnych typu tosoba:
- Inicjalizującą zmienną typu tosoba losowymi wartościami;
Prototyp:
void Inicjuj(tosoba& r);
-
Wyprowadzającą zawartość zmiennej typu tosoba na ekran;
-
Dopisującą zmienną typu tosoba na końcu pliku o podanej nazwie;
Prototyp:
void Fdopisz(FILE *f, char *nazwa, const tosoba *os);
- Odczytującą zmienną z zadanej pozycji w pliku o podanej nazwie i zapisującą daną do os;
Prototyp:
void Fczytaj (FILE *f, char *nazwa, long poz, tosoba *os);
- Wstawiającą, pomiędzy istniejące dane, nową daną na zadanej pozycji w pliku o podanej nazwie;
Prototyp:
void Fwstaw (FILE *f, char *nazwa, long poz, const tosoba *os);
- Usuwającą element z zadanej pozycji w pliku i zapisującą daną do os;
Prototyp:
void Fusun (FILE *f, char *nazwa, long poz, tosoba *os).
Przetestować opracowane funkcje w programie.
Napisałem wszystkie te funkcje oprócz Fusun gdyż zauważyłem, ze valgrind wywala błędy w funkcjach:
- Fdopisz
- Fwstaw
Tutaj jest mój kod:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
struct tosoba7{
char naz[20];
long id;
};
void inicjalizuj(struct tosoba7 *os){
os->id=rand()%1111;
strcpy(os->naz,"nazw");
}
void wypisz7(struct tosoba7 *os){
printf("%s \n%ld\n",os->naz,os->id);
}
void Fdopisz(FILE *f, char *nazwa, const struct tosoba7 *os){
f=fopen(nazwa,"a");
if(f){
//Teoretycznie fseek jest niepotrzebne dla gdyż atrybut "a" automatycznie ustawia wskaźnik na koniec pliku.
//fseek(f,0,2);
fwrite(os,sizeof(struct tosoba7),1,f);
fclose(f);
}
}
void Fczytaj(FILE *f, char *nazwa, long poz, struct tosoba7 *os){
f=fopen(nazwa,"r");
if(f){
fseek(f,sizeof(struct tosoba7)*poz,0);
fread(os,sizeof(struct tosoba7),1,f);
fclose(f);
}
}
void Fwstaw(FILE *f, char *nazwa, long poz, struct tosoba7 *os){
struct tosoba7 *tab=0;
int iloscObiektow=0;
f=fopen(nazwa,"r");
if(f){
//ustawienie wskaźnika na koniec pliku, żeby do obiektu rozmiar wczytać rozmiar pliku
fseek(f,0,2);
long rozmiar=ftell(f);
iloscObiektow=rozmiar/sizeof(struct tosoba7);
//przestawienie wskaźnika na początek pliki, żeby wczytać wszystkie pliki do tablicy dynamicznej
fseek(f,0,0);
tab=(struct tosoba7*)malloc(iloscObiektow*sizeof(struct tosoba7));
fread(tab,sizeof(struct tosoba7),iloscObiektow,f);
//realokowanie pamięci na komórkę o jeden większą, w której będzie dodawany nowy obiekt
tab=(struct tosoba7*)realloc(tab,(iloscObiektow+1)*sizeof(struct tosoba7));
//ustalenie pozycji dla nowego obiektu
int i;
for(i=iloscObiektow+1;i>=0;i--){
if(i!=poz){
tab[i]=tab[i-1];
}
else if(i==poz){
tab[i]=*os;
break;
}
}
fclose(f);
}
f=fopen(nazwa,"w");
if(f){
fwrite(tab,sizeof(struct tosoba7),iloscObiektow+1,f);
fclose(f);
}
if(tab)free(tab);
}
//void Fusun(FILE *f, char *nazwa, long poz, struct tosoba7 *os){
//}
int main(void){
srand(time(NULL));
FILE *init=fopen("zad7.txt","w");
if(init){
fclose(init);
}
struct tosoba7 s;
inicjalizuj(&s);
struct tosoba7 x;
inicjalizuj(&x);
printf("Dwa pierwsze obiekty:\n");
wypisz7(&s);
wypisz7(&x);
FILE *plik=0;
Fdopisz(plik,"zad7.txt",&s);
Fdopisz(plik,"zad7.txt",&x);
struct tosoba7 c;
Fczytaj(plik,"zad7.txt",1,&c);
printf("\nPlik odczytany z pozycji nr 1:\n");
printf("%s\n%ld\n",c.naz,c.id);
struct tosoba7 sx;
inicjalizuj(&sx);
printf("\nObiekt do pisania na pozycje nr 1:\n");
wypisz7(&sx);
Fwstaw(plik,"zad7.txt",1,&sx);
printf("\nPo dopisaniu na poz nr 1\n");
struct tosoba7 tab[3];
int i;
for(i=0;i<3;i++)
Fczytaj(plik,"zad7.txt",i,&tab[i]);
for(i=0;i<3;i++)
wypisz7(&tab[i]);
return 0;
}
Gdzie może być błąd? Nie mogę sobie z tym poradzić?
Pozdrawiam
Grzesiek
PS: U mnie typ nazywa się tosoba7 od numeru zadania.