Kochani, mam taką funkcję, poznaną na zajęciach i chciałabym się dowiedzieć dlaczego w pliku wynikowym outv2.txt nie mam tego samego co w in.txt. Jaka jest tego przyczyna? Co robię źle?
- Nie wrzucaj nigdy zdjęć kodu źródłowego, a tekst.
- Pokaż cały kod.
Przecież dumpujesz strukturę binarnie. Więc dla czego w ogóle oczekujesz, że int
(bo zakładam, że tym jest osoba.rok
) będzie tekstowo przedstawiony jako 2000
? Przecież to zupełnie różne reprezentacje.
Patryk27 napisał(a):
- Nie wrzucaj nigdy zdjęć kodu źródłowego, a tekst.
- Pokaż cały kod.
przepraszam, mój pierwszy wpis :/
#include <string.h>
#define X 10
#define MAX 20
typedef struct
{
char imie [MAX+1];
char nazwisko [MAX+1];
char rok [MAX+1];
} osoba;
int OdczytPliku(const char* nazwa,osoba tab[])
{
int i;
FILE *plik=fopen(nazwa, "r");
for( i=0; i<X; i++)
{
if((fscanf(plik, "%s%s%s", tab[i].imie, tab[i].nazwisko, tab[i].rok))==EOF)
break;
}
return i;
fclose(plik);
}
int MinRok(osoba tab[], int Y)
{
int i,j=0,minrok;
int mini=atoi(tab[0].rok);
for(i=0; i<Y; i++)
{
if(atoi(tab[i].rok)<mini)
{
mini=atoi(tab[i].rok);
}
}
return mini;
}
void TworzPlikWynikowy_v2(const char *nazwa, osoba tab[], int Y, int mini)
{
FILE *plik=fopen(nazwa, "wb");
if(plik==NULL)return;
for(int i=0; i<Y; i++)
{
fwrite(tab+i,sizeof(osoba), 1, plik);
fprintf(plik,"\n");
}
fclose(plik);
}
int main()
{
int licznik, min_rok;
osoba tab[X];
licznik=OdczytPliku("in.dat", tab);
if(licznik==0)
return 1;
//printf("%s", tab[1].imie);
min_rok=MinRok(tab,licznik);
// printf("%d", min_rok);
//TworzPlikWynikowy("out5.txt",tab,licznik, min_rok);
TworzPlikWynikowy_v2("out_v2_5.txt",tab, licznik,min_rok);
return 0;
}
to cały program, a osoba.rok nie może być u mnie int'em skoro muszę wziąć dane z pliku testowego. Chyba że da się to jakoś zrobić ?
Dla wytłumaczenia uprośćmy nieco Twój kod:
typedef struct
{
char imie [32];
} osoba;
/* ... */
fscanf(plik, "%s", tab[i].imie)
/* ... */
fwrite(tab+i,sizeof(osoba), 1, plik);
Pierwszy "problem" stanowi instrukcja fscanf
: załóżmy, że wczytane imię ma 5 znaków - jak myślisz, co będzie znajdowało się pod imie[6]
?
...śpiesząc z odpowiedzią: wszystko za imie[5]
(w którym znajduje się null terminator
) zawiera śmieci, które akurat przypadkiem znalazły się w tym miejscu pamięci; dzieje się tak ponieważ fscanf
automatycznie nie czyści buforu wyjściowego.
Drugi problem: nawet gdybyś w jakiś sposób dopełniła imie
spacjami (czyli mielibyśmy np. Wojtek\0\spacja\spacja\spacja\spacja
), wystąpiłby problem z fwrite
, które nie wiedziałoby, że tak naprawdę tych spacji w swoim pliku wyjściowym nie potrzebujesz :-)
Rozwiązanie jest jednak proste i wymaga raptem drobnych zmian w części zapisującej dane do pliku:
fwrite(tab[i].imie, strlen(tab[i].imie), 1, plik);
// + ewentualnie `fwrite` dla spacji
// fwrite(tab[i].nazwisko, strlen(tab[i].nazwisko), 1, plik);
// + ewentualnie `fwrite` dla spacji
// fwrite(tab[i].rok, strlen(tab[i].rok), 1, plik);