Pobieranie do struktury z pliku w C

0

Witam,
Mam problem z pobraniem danych z pliku do tablicy strukturowej.
Program się wysypuje,i kompilator wypisuje ostrzeżenie w lini 16.
czyli w tej linii

for(fscanf(plik,"%s",&(pocz.imie));(int)(pocz.imie)!=EOF;i++)

cały program:

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

typedef struct{
	char imie[20];
	char nazwisko[20];
	int rok;
}Osoba;

int main(int argc, char *argv[]) {
	FILE *plik=fopen("plik.txt","r");
	Osoba pocz;
	Osoba tab[20];
	int i=0,x;
	for(fscanf(plik,"%s",&(pocz.imie));(int)(pocz.imie)!=EOF;i++){
		for(x=0;pocz.imie[x]!='\0';x++){
		tab[i].imie[x]=pocz.imie[x];}
		fscanf(plik,"%s",tab[i].nazwisko);
		fscanf(plik,"%d",&tab[i].rok);
		fscanf(plik,"%s",&(pocz.imie));
	}
}

Pomoże ktoś z naprawą?

1

Ta część jest zła

(int)(pocz.imie)!=EOF

Bo nie możesz z tablicy znaków zrobić inta.

0

a jak można to naprawić? bo nie mam innego pomysłu ;(

1

Powiedz mi jak masz oddzielone dane bo nie wiem po co jest

Osoba pocz;

Oraz ta pętla for w for.

Oddzielasz np. spacjami a potem nowa linia to nowa osoba czy jak?

0

W pliku w każdej linii są oddzielone tabulatorami np:
Jan Kowalski 1988
Adam Nowak 1922
...

do zmiennej Osoba pocz wczytuję imię z pliku. potem sprawdzam, czy fscanf(plik,"%s",&(pocz.imie)) pobrało jakąkolwiek daną. jeśli tak, to znaczy że mogę pobrać nazwisko i rok urodzenia.
Ten for w forze przepisuje imie ze zmiennej do tablicy i działa w 100% poprawnie

1

Można uprościć ten kod do:

int main(int argc, char *argv[]) {
    FILE *plik=fopen("test.txt","r");
    Osoba tab[20];
    
    for(int i = 0; i < 20; i++)
    {
        /*
         * 3 to oczekiwana ilość pomyślnych konwersji
         * Dlatego sprawdzamy czy wartość jest inna niż 3
         * jeżeli tak - to nastąpił jakiś problem
         * i wychodzimy z pętli
         * */
        if(fscanf(plik,"%s\t%s\t%d", tab[i].imie, tab[i].nazwisko, &(tab[i].rok)) != 3)
        {
            break;
        }
    }
    fclose(plik); // EDIT - Zamknięcie pliku
}

EDIT: @kamilm758 - pamiętaj o zamykaniu pliku.

0

hmm mam pytanie
dlaczego

fscanf(plik,"%s\t%s\t%d", tab[i].imie, tab[i].nazwisko, &(tab[i].rok))

jest przyrównane do 3

1

Bo są 3 pola: imie, nazwisko oraz rok urodzenia.

0

ale ta funkcja służy do pobierania danych z pliku. czy można ją tak po prostu przyrównać do liczby? ona coś zwraca że można ją przyrównać?

1

Ta funkcja wstawia dane tak jak podaliśmy, zgodnie z formatem. Następnie zwraca ilość udanych konwersji.

0

ok rozumiem. tylko jest 1 problem.
prze tym jak break zadziała, to funkcja fscanf jeszcze się wykona i pobierze jakieś śmieci. jak temu zaradzić?
bo np, jak w pliku są 2 linie to pętla przejdzie 3 razy i dopiero zadziała break

1

Można wprowadzić zmienną size która będzie mówiła ile danych jest w tablicy.

int main(int argc, char *argv[]) {
    FILE *plik=fopen("test.txt","r");
    Osoba tab[20];

    int size = 20; // 20 to rozmiar tablicy tab. To w przypadku kiedy wszystkie 20 konwersji będzie pomyślnych.
    for(int i = 0; i < 20; i++)
    {
        /*
         * 3 to oczekiwana ilość pomyślnych konwersji
         * Dlatego sprawdzamy czy wartość jest inna niż 3
         * jeżeli tak - to nastąpił jakiś problem
         * i wychodzimy z pętli
         * */
        if(fscanf(plik,"%s\t%s\t%d", tab[i].imie, tab[i].nazwisko, &(tab[i].rok)) != 3)
        {
            size = i; // Dzięki temu że przypisujemy i do size będziemy mieli -1. Czyli jeżeli za 3 razem będzie źle to size będzie 2.
            break;
        }
    }

    for(int i = 0; i < size; i++) // Wyświetlanie danych
    {
        printf("%s %s: %d\n", tab[i].imie, tab[i].nazwisko, tab[i].rok);
    }
    fclose(plik);
}
0

ok wielkie dzięki. teraz działa dobrze.

0

hmm a co sądzisz o takim rozwiązaniu?

while (!feof(plik)) {
      fscanf(plik, "%s %s %d\n", tab[i].imie, tab[i].nazwisko, &tab[i].rok);
      i++;
    }
1

A co się stanie kiedy będziesz miał za dużo plików i zbyt małą tablicę? Będziesz wpisywał wartości pod adresy które nie należą do tablicy. Poza tym feof będzie prawdą kiedy będziesz próbował czytać EOF czyli o jedną iteracje pętli za dużo.

0

czyli wyjdzie na to samo, że bym musiał odjąć 1 od rozmiaru tablicy, i trzeba dać warunek że pętla nie może wykonać się więcej niż 20 razy.
jeszcze raz wielkie dzięki

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