Czytanie struktury z pliku w C


(M Kostek) #1

Witam, mam do napisania baze danych, która ma zawierać min 50 abonamentów. Potem mam sortować wg nazwiska, zapisywać i odczytywać do pliku i takie tam.. czego dusza zapragnie! Narazie zrobiłem jakieś tam 3 osoby, żeby w ogóle spróbować no i niestety.. poległem już na początku

mam coś takiego

#include 

#include 


const int N=3;


void main()

{

	int licznik;

	struct KSIEGA

	{

		int lp;

		char nazwisko[20];

		char imie[15];

		int numer;

		char adres;

	};


	KSIEGA osoba[N];

	FILE *plik;

	plik = fopen("C:/Users/Kostek/Desktop/Programy/VB Programy/Baza danych/baza.txt","r"); //wczytanie bazy z pliku


	if( plik == NULL) //sprawdzenie, czy baza wczytana poprawnie

		printf("Nie moge znalezc bazy. Cos zepsules Marcin :(");

	else

	{

		printf("Baza wczytana pomyslnie!\n\n");

		for (int i=0; i<=N; i++)

			fscanf(plik,"%d %s %s %d %s",&(osoba[i].lp), osoba[i].nazwisko, osoba[i].imie, &(osoba[i].numer), osoba[i].adres);

	}

	fclose(plik);

	for (int i=0; i<=N; i++)

		printf("%d %s %s %d %s",osoba[i].lp, osoba[i].nazwisko, osoba[i].imie, osoba[i].numer, osoba[i].adres);

	getch();

}

Program się niby kompiluje, ale potem odrazu zwiecha. Na ekranie widzę komunikat, że baza wczytana pomyślnie, więc bląd jest gdzieś od tego miejsca (tak myślę)

fscanf(plik,"%d %s %s %d %s",&(osoba[i].lp), osoba[i].nazwisko, osoba[i].imie, &(osoba[i].numer), osoba[i].adres);

Generalnie w tym pliku txt wygląda to tak że przykładowo

1 Marcin Kostyszyn 1653416 Wrocław enter

2 dane dane numer miasto enter

Jakieś sugestie, czemu się sypie?


(Johny) #2

struct KSIEGA

{

int lp;

char nazwisko[20];

char imie[15];

int numer;

char adres[30]; //nie podałeś ile znaków i to też jest odwołanie do nieistniejących elementów

};

Moim zdaniem appersandy powinny być przy zmiennych,nie przy nawiasach (czyli zamiast &(osoba.imię) (&osoba imię,&osoba_.nazwisko)_

fscanf(plik,"%d %s %s %d %s",&osoba .lp, &osoba.nazwisko, &osoba .imie, &osoba.numer, &osoba__.adres);

Jeśli nie wyłuskasz adresu uppersandem z każdej zmiennej,funkcja się posypie i z tym jest problem.

dla pewności poczytaj o funkcji fscanf.


(M Kostek) #3

Brak rozmiaru przy char adres, to było to. Głupie niedopatrzenie :slight_smile:

A ampersandy są dobrze, bo już elegancko wyświetla, ide walczyć dalej, jakby co, będę pytał :slight_smile:

A własnie.. jedno pytanie. Bo w opisie zadania, wykładowca zaznaczył, że nie mamy używać referencji. Więc tam gdzie mam ampersandy, to na te zmienne zrobie wskaźniki i nie powinien się juz czepiać?

No i własnie.. Poratuj znowu, ja pierwszy raz pracuje na structach i plikach. Chcę to przerobić na wskaźniki, wyczytałem, że ma wyglądać mniej więcej jakoś tak

#include 

#include 


const int N=3;


void main()

{

	int licznik;

	struct KSIEGA

	{

		int lp;

		char nazwisko[20];

		char imie[12];

		int numer;

		char adres[20];

	};


	KSIEGA osoba[N];

	KSIEGA* wsk = &osoba;


	FILE *plik;

	plik = fopen("C:/Users/Kostek/Desktop/Programy/VB Programy/Baza danych/baza.txt","r"); //wczytanie bazy z pliku


	if( plik == NULL) //sprawdzenie, czy baza wczytana poprawnie

		printf("Nie moge znalezc bazy. Cos zepsules Marcin :(");

	else

	{

		for (int i=0; ( !feof(plik) )&& i
			fscanf(plik,"%d %s %s %d %s",(*wsk).lp, (*wsk).nazwisko, (*wsk).imie, (*wsk).numer, (*wsk).adres);						

		printf("Baza wczytana pomyslnie!\n\n");

	}

	fclose(plik);

	for (int i=0; i
		printf("%d %s\t%s \t%d\t%s\n",(*wsk).lp, (*wsk).nazwisko, (*wsk).imie, (*wsk).numer, (*wsk).adres);

	getch();

}

Ale nie hasa. Error 1 error C2440: 'initializing' : cannot convert from 'main::KSIEGA (*)[3]' to 'main::KSIEGA *' c:\users\kostek\desktop\programy\vb programy\baza danych\baza danych\ksiega.cpp 20 Baza danych Taki bład jest Error 1 error C2440: 'initializing' : cannot convert from 'main::KSIEGA (*)[3]' to 'main::KSIEGA *' c:\users\kostek\desktop\programy\vb programy\baza danych\baza danych\ksiega.cpp 20 Baza danych to jest 20 linijka czyli tu

KSIEGA* wsk = &osoba;

Jeśli usunę z przed KSIEGA rozmiar N, to się niby kompiluje, ale znowu zwiecha, więc znowu gdzieś jakieś adresowanie źle jest chyba :confused: Ok już doczytałem. Pisząc KSIEGA *wsk = &osoba[N]; robię jakby wskaźnik na wskaźnik. Ma być tak

KSIEGA *wsk = osoba;

Ale mimo wszystko program dalej nie działa. Kompilacja i potem zwiecha


(Blapiter) #4

"osoba" jest tablicą więc albo tak:

KSIEGA* wsk = osoba;

albo tak:

KSIEGA* wsk = &osoba[0];

reszty kodu nie analizowałem


(M Kostek) #5

To własnie w reszcie kodu nie mogę znaleźć błędu

Coś źle adresuję w tej pętli chyba

for (int i=0; ( !feof(plik) )&& i
	fscanf(plik,"%d %s %s %d %s",(*wsk).lp, (*wsk).nazwisko, (*wsk).imie, (*wsk).numer, (*wsk).adres);

(Blapiter) #6

Na szybko . Jeżeli jest to zmienna to tak można

float f;

   float * wsk = &f;

  fscanf (pFile, "%f ", wsk);

a jak tablica to nie można mieć na niej wskaźnika czyli

char str [80];

 fscanf (pFile, "%s", str);

To wykorzystaj u siebie


(M Kostek) #7

Z tamtymi problemami sobie poradziłem

A teraz coś innego mnie trapi, nie mogę używać zmiennych globalnych w programie

A już przerobiłem na funkcje, ale żeby działał muszę przed wszystkim zrobić

struct KSIEGA

	{

		long unsigned lp;

		char nazwisko[20];

		char imie[12];

		int numer;

		char adres[20];

	};

czyli jakby globalnie deklaruje tą strukture i niby zmienne w niej? Więc to jest zgodnie moimi zasadami, że nie mogę uzywac zmiennych globalnych? Cały kod wygląda teraz tak

#include 

#include 

const int N=50;



struct KSIEGA

	{

		long unsigned lp;

		char nazwisko[20];

		char imie[12];

		int numer;

		char adres[20];

	};



void odczyt (KSIEGA *wsk)																	

{


	for (int i=0; i<9; i++, wsk++) //Odczyt pierwszej dziewiatki, zeby bylo rowno

		printf("%d %s\t %s \t%d\t%s\n",(*wsk).lp, (*wsk).nazwisko, (*wsk).imie, (*wsk).numer, (*wsk).adres);

	for (int i=9; i
		printf("%d %s\t %s \t%d\t%s\n",(*wsk).lp, (*wsk).nazwisko, (*wsk).imie, (*wsk).numer, (*wsk).adres);

	getch();

}


void main()

{

	int wybor;

	KSIEGA osoba[N];


	KSIEGA *wsk = osoba;

	FILE *plik;

	plik = fopen("C:/Users/Kostek/Desktop/Programy/VB Programy/Baza danych/baza.txt","r"); //wczytanie bazy z pliku


	if( plik == NULL) //sprawdzenie, czy baza wczytana poprawnie

		printf("Nie moge znalezc bazy. Cos zepsules Marcin :(");

	else

	{

		for (int i=0; ( !feof(plik) )&& i
			fscanf(plik,"%d %s %s %d %s", &((*wsk).lp), &((*wsk).nazwisko), &((*wsk).imie), &((*wsk).numer), &((*wsk).adres));

		printf("Baza wczytana pomyslnie!\n\n");	

	}

	fclose(plik);

	wsk = osoba;



	printf("\t\tMENU UZYTKOWNIKA\n\nCo chcesz zrobic?\n"

		   "1. Wyswietl baze danych\n\n"

		   "Twoj wybor: ");


	scanf("%d",&wybor);

	switch(wybor)

	{

	case 1:

		printf("\nLP NAZWISKO\t IMIE\t\tNUMER\t\tMIASTO\n\n");


		odczyt(osoba);

		break;

	}


}

(Blapiter) #8

Jak już robimy w C to trzymajmy się ANSI C:

#include 

#include 


const int N=2;

int i = 0;

struct KSIEGA

{

    int lp;

    char nazwisko[20];

    char imie[12];

    int numer;

    char adres[20];

};

struct KSIEGA * osoba = NULL; // GLOBALNA KSIEGA

void odczyt();


int main(int argc, char **argv)

{

    osoba = (struct KSIEGA *) malloc(sizeof(struct KSIEGA)*N);

    FILE *plik;

    int wybor;

    plik = fopen("asd.txt","r");

    if( plik == NULL)

        printf("Nie moge znalezc bazy");

    else

    {

        for (i=0; ( !feof(plik) )&& i
        fscanf(plik,"%d %s %s %d %s",&osoba[i].lp, osoba[i].nazwisko, osoba[i].imie, &osoba[i].numer, osoba[i].adres);

        printf("Baza wczytana pomyslnie!\n\n");

    }

    fclose(plik);

    printf("\t\tMENU UZYTKOWNIKA\n\nCo chcesz zrobic?\n"

             "1. Wyswietl baze danych\n\n"

             "Twoj wybor: ");

    scanf("%d",&wybor);

    switch(wybor)

    {

    case 1:

      printf("\nLP NAZWISKO\t IMIE\t\tNUMER\t\tMIASTO\n\n");

      odczyt();

      break;

    }

    free(osoba);

    getch();

    return 0;

}


void odczyt()

{

   for (i=0; i
        printf("%d %s\t%s \t%d\t%s\n",osoba[i].lp, osoba[i].nazwisko, osoba[i].imie, osoba[i].numer, osoba[i].adres);

}