Pobieranie do struktury z pliku w C

Pobieranie do struktury z pliku w C
K7
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:98
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

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

cały program:

Kopiuj
#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ą?

atmal
  • Rejestracja:około 8 lat
  • Ostatnio:9 dni
  • Postów:913
1

Ta część jest zła

Kopiuj
(int)(pocz.imie)!=EOF

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


Failure of one test is a tragedy, failure of fifty is a statistic.
K7
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:98
0

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

atmal
  • Rejestracja:około 8 lat
  • Ostatnio:9 dni
  • Postów:913
1

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

Kopiuj
Osoba pocz;

Oraz ta pętla for w for.

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


Failure of one test is a tragedy, failure of fifty is a statistic.
K7
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:98
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

atmal
  • Rejestracja:około 8 lat
  • Ostatnio:9 dni
  • Postów:913
1

Można uprościć ten kod do:

Kopiuj
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.


Failure of one test is a tragedy, failure of fifty is a statistic.
edytowany 2x, ostatnio: atmal
MO
Super... a sam się ten plik zamknie? Wyciek zasobów...
atmal
Dzięki @Mokrowski za czujność ;)
K7
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:98
0

hmm mam pytanie
dlaczego

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

jest przyrównane do 3

atmal
  • Rejestracja:około 8 lat
  • Ostatnio:9 dni
  • Postów:913
1

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


Failure of one test is a tragedy, failure of fifty is a statistic.
K7
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:98
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ć?

atmal
  • Rejestracja:około 8 lat
  • Ostatnio:9 dni
  • Postów:913
1

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


Failure of one test is a tragedy, failure of fifty is a statistic.
K7
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:98
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

atmal
  • Rejestracja:około 8 lat
  • Ostatnio:9 dni
  • Postów:913
1

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

Kopiuj
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);
}

Failure of one test is a tragedy, failure of fifty is a statistic.
K7
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:98
0

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

K7
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:98
0

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

Kopiuj
while (!feof(plik)) {
      fscanf(plik, "%s %s %d\n", tab[i].imie, tab[i].nazwisko, &tab[i].rok);
      i++;
    }
atmal
  • Rejestracja:około 8 lat
  • Ostatnio:9 dni
  • Postów:913
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.


Failure of one test is a tragedy, failure of fifty is a statistic.
K7
  • Rejestracja:ponad 7 lat
  • Ostatnio:ponad 3 lata
  • Postów:98
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

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.