Zapisywanie do pliku i odczyt - struct

0

Witam serdecznie,
moim zadaniem jest "Napisać program, który poprosi użytkownika o podanie danych pięciu osób. Dane te to: imię, wzrost (w cm) i waga (w kg). Dane o osobach należy przechować w zmiennych typu złożonego (struktura). Następnie dane o osobach zapisać do pliku (LPP_8.dat). Przed zapisaniem danych o osobach, należy do pliku zapisać liczbę osób, których dane plik będzie zawierał."

Mój kod wygląda następująco :

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

struct Dane {
	char imie[50];
	float wzrost;
	float waga;
}s1,s2,s3,s4,s5;


int main(int argc, char *argv[]) {
	
	FILE *fp;
	
	puts("podaj dane 5 osob : imie, wzrost, waga:");
	scanf("%s %d %d",&s1.imie,&s1.waga,&s1.wzrost);
	scanf("%s %d %d",&s2.imie,&s2.waga,&s2.wzrost);
	scanf("%s %d %d",&s3.imie,&s3.waga,&s3.wzrost);
	scanf("%s %d %d",&s4.imie,&s4.waga,&s4.wzrost);
	scanf("%s %d %d",&s5.imie,&s5.waga,&s5.wzrost);
	
	if((fp=fopen("test_gr3.dat","w"))==NULL){
		printf("nie mogę otworzyc pliku test_gr1.txt do odczytu !");
		exit(1);
	}
	int N = 5;
	fwrite(&N,sizeof(N),1,fp);
	fwrite(&s1,sizeof(s1),2,fp);
	fwrite(&s2,sizeof(s2),3,fp);
	fwrite(&s3,sizeof(s3),4,fp)	;
	fwrite(&s4,sizeof(s4),5,fp)	;
	fwrite(&s5,sizeof(s5),6,fp)	;
	fclose(fp);
	if ((fp=fopen("test_gr3.dat", "r")) == NULL) { 
		printf ("Nie mogę otworzyć pliku test_gr1.txt do odczytu!\n");
		exit(1); 
		} 
	char odczyt[101];
	while(fscanf(fp,"%100s",odczyt)!=EOF){
		printf("%s ",odczyt);
	}
	
	return 0;
}

Program nie odczytuje poprawnie w sumie nic.. wychodzą jakieś krzaczki i mnóstwo spacji.
Niestety nie potrafię znaleźć błędu w tym programie.

Miłoby było jakby ktoś mi to wytłumaczył wręcz łopatologicznie, gdzie i czemu program się wysypuje.

5

%d wczytuje do typu int. Poza tym, jeśli w zadaniu będzie 1000 osób to zrobisz 1000 zmiennych i 1000 wywołań scanfa? Aha, trzeci argument fwrite nie działa tak jak myślisz. http://en.cppreference.com/w/cpp/io/c/fwrite

0

Dodam tylko że kompilator przy zapisywaniu struktur w ten sposób może dodać bajty paddingu do struktury, wtedy masz trochę nadmiarowych bajtów w pliku. Aby tego uniknąć, w GCC używasz atrybutu __attribute__((packed)) przed średnikiem w ostatniej klamrze struktury.

3

Radze zacząć od byle kursu - rozdziały: tablice, pętle.

0

No ok. wziąłem pętle na scanf i również do fwrite. Rzeczywiście nie zwróciłem uwagi że miałem wpisane %d do floata ale to już poprawiłem. Zapisuje jednakże mi wyłącznie tylko imie a później jakieś dziwne znaki, czyli wciąż to nie to o czym myślę..

0

Mieszasz "systemy walutowe" zapisujesz binarnie (choć nie otwierasz pliku do takiego zapisu - więc mogą pojawić się błędy), 2 wczytać musisz dane binarne więc fscanf jest bez sensu, on jest do odczytu danych tekstowych!

0

Tak, to też wtedy poprawiłem. Używam fread do odczytu danych jednakże coś się wysypuje. W tej chwili mój kod wygląda następująco :

 #include <stdio.h>
#include <stdlib.h>
int i;
struct Dane {
	char imie[50];
	int wzrost;
	int waga;
}s[4];


int main(int argc, char *argv[]) {
	
	FILE *fp;
	puts("podaj dane 5 osob : imie, wzrost, waga:");
	
	for(i=0 ; i <5 ; i++){
	scanf("%s %d %d",&s[i].imie,&s[i].waga,&s[i].wzrost);
}
	int j;


	if((fp=fopen("test_gr3.txt","w"))==NULL){
		printf("nie mogę otworzyc pliku test_gr1.txt do odczytu !");
		exit(1);
	}
	int N = 5;
	fwrite(&N,sizeof(N),1,fp);
	for(i=0 ; i <5 ;i++){
		fwrite(&s[i],sizeof(s[i]),4,fp);
	}
	fclose(fp);
	if ((fp=fopen("test_gr3.txt", "r")) == NULL) { 
		printf ("Nie mogę otworzyć pliku test_gr1.txt do odczytu!\n");
		exit(1); 
		} 
	int odczytano[4];
	for(i=0;i<5;i++){
		odczytano[i]=fread(&s[i],sizeof(s[i]),5,fp);
	}
	for(i=0;i<5;i++){
		printf("%s",odczytano[i]);
	}

	return 0;
}

Niestety nie umiem sobie z tym poradzić

2
  1. masz s[4];, a
 for(i=0 ; i <5 ; i++){
    scanf("%s %d %d",&s[i].imie,&s[i].waga,&s[i].wzrost);

wychodzisz poza pamięć!

  1. Nie wiziąłeś tez do siebie, by otwierac plik wtrybie do odczytu/zapisu binarnego

  2. Po otwarcu pliku do odczytu odczytujesz od początku dane do struktury, a przecież pierwsze dane zapisałeś inne!

0

W jaki więc sposób mam "naprawić" program ?

0

Nie mogę edytować posta poprzedniego więc musze pisać następny.

Nie wydaję mi się żebym wychodził poza pamięć. skoro mam s[4] to mam wartości s[0],s[1],s[2],s[3],s[4] a wiec 5 elementow. Skoro ustawiam warunek for i<5 a rozpoczynam "liczenie" od 0 to mam 0,1,2,3,4. Gdy wartosc osiaga 5 warunek nie jest spelniony i for sie nie robi

4

Tablica czteroelementowa ma - (wait for it!) - cztery elementy, o indeksach 0, 1, 2 i 3.

0

Sorki, coś mi się w głowie ostro popierzyło. Sic !

0

Jest ktoś w stanie zmienić mój kod na działający ? Bo nie ogarniam tego

0
  1. Nie rozumiesz inkrementacji: http://4programmers.net/Forum/1101404
  2. 5 razy zapisujesz 4 rekordy, po czym 5 razy odczytujesz 5 rekordów, WTF?
fp=fopen("test_gr3.txt","w");
fwrite(s,sizeof(Dane),5,fp); // zapisujemy od razu 5 rekordów
fclose(fp);
fp=fopen("test_gr3.txt","r");
int readed=fread(s,sizeof(Dane),5,fp); // odczytujemy od razu wszystkie rekordy ale nie więcej niż 5
printf("wczytano %d rekordów\n",readed);
0

Dzięki, teraz wiem jak już działa ta funkcja. Teraz rozumiem czemu program się wywalał. Pozostało mi tylko poprawić kod

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