Wczytywanie listy z pliku tekstowego

0

Witam. Dane w pliku tekstowym:

Kowalski Jan 18
Nowak Andrzej 20

Mój kod:

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

struct Student{
	char nazwisko[15];
	char imie[15];
	int wiek;
};
	

int main() {
	struct Student *pocz;
	struct Student *pom=pocz;
	
	FILE* plik=fopen("student.txt", "r");
	
	while(pom->nast!=NULL){
		fscanf(plik, "%s %s %d\n", pom->nazwisko, pom->imie, &pom->wiek);
		pom=pom->nast;
		
		
			
	}
	fclose(plik);
	return 0;
}

Program się wiesza i wyłącza. Co tutaj jest źle? Jak wczytać dane do listy?

0
HipolitZabujca napisał(a):

Program się wiesza i wyłącza. Co tutaj jest źle? Jak wczytać dane do listy?
Chrzani Waść. Program nawet się nie kompiluje, zaś kompilator wskazuje błędy.
Przykład listy: http://4programmers.net/Forum/C_i_C++/262765-listy_dodawanie_pierwszego_el?p=1203991#id1203991

0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct Student{
    char nazwisko[15];
    char imie[15];
    int wiek;
    struct Student *nast;
};
 
 
int main() {
    struct Student *pocz;
    struct Student *pom=pocz;
    
 	FILE* plik=fopen("student.txt", "r");
 	while(pom!=NULL){
 		fscanf(plik, "%s %s %d", pom->nazwisko, pom->imie, &pom->wiek);
		 printf("%s %s %d", pom->nazwisko, pom->imie, pom->wiek);
 		pom=pom->nast;	
	}
	fclose(plik);

    return 0;
}

Dzięki za link, na razie próbuję samemu coś wykombinować. Teraz program się nie wyłącza, ale też nic nie wyświetla.
Ma to w ogóle sens?

0

Program zwyczajnie maże po pamięci.

  1. Nigdzie nie inicjalizujesz pocz;
  2. Nigdzie nie przydzielasz pamięci pod obiekt struct Student;
  3. Pętla ma być while(fscanf(...)==3);
0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct Student{
    char nazwisko[15];
    char imie[15];
    int wiek;
    struct Student *nast;
};
 
 
int main() {
    
    return 0;
}

To od początku. Mam utworzoną listę. Co dalej?

0

Nie masz utworzonej listy, masz zdefiniowaną strukturę elementu listy.
Dalej czytasz byle jaki kurs, po czym jeżeli nadal nie będziesz rozumieć jakiegoś słowa z: http://4programmers.net/Forum/1204061
to powiedz którego - wyjaśnię.

0

Dobra, rozumiem. Mam zdefiniowaną strukturę listy ( tak jakby wzór ) i teraz muszę ją utworzyć. I teraz pojawia się pytanie jak?
Wykorzystać malloca?

0

Może to być malloc, calloc lub realloc.
Czy tak zamierzasz pisać program wiersz po wierszu?
Czy jesteś świadom że w ten sposób zejdzie ci jakiś tydzień na ten program a i tak nic umieć nie będziesz?
Czy przeczytałeś jakiś kurs?

0
_13th_Dragon napisał(a):

Program zwyczajnie maże po pamięci.

  1. Nigdzie nie inicjalizujesz pocz;
  2. Nigdzie nie przydzielasz pamięci pod obiekt struct Student;
  3. Pętla ma być while(fscanf(...)==3);

Jeżeli chodzi o te podpunkty to nie rozumiem 1 i 2.

Nie zamierzam pisać linijka po linijce. Robiłem taki sam program z użyciem samych struktur i wszystko grało. Problemem jest zrozumienie czym jest lista. Ja rozumiem to tak, że jest to dynamiczna struktura.
Czyli jest tak jak w tablicach dynamicznych, należy samemu przydzielić pamięć?

1

Ad 1. Zainicjalizować/przypisać np. zmienna=13;
Ad 2. Którego słowa nie rozumiesz?

HipolitZabujca napisał(a):

Problemem jest zrozumienie czym jest lista.
Doprawdy? Taki to problem na Wikipedię zajrzeć https://pl.wikipedia.org/wiki/Lista? Nawet obrazek jest.

Tak należy przydzielać pamięć do każdej dynamicznej struktury, przy czym tylko dla dynamicznych tablic robimy to raz na cała tabelkę rekordów, dla pozostałych przydzielamy na każdy rekord osobno.

Zauważyłem że próbujesz pomagać innym, wiec masz:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct Student
  {
   char nazwisko[15];
   char imie[15];
   int wiek;
   struct Student *nast;
  };
 
int main()
  {
   struct Student dane,*tmp,*tail=NULL,*head=NULL; /* =NULL; -> inicjalizacja */
   FILE* plik=fopen("student.txt", "r");
   while(fscanf(plik, "%s %s %d",dane.nazwisko,dane.imie,&dane.wiek)==3) /* dopóki udało się wczytać */
     {
      tmp=(struct Student*)malloc(sizeof(struct Student)); /* przydzielenie pamięci */
      *tmp=dane; /* przekopiowanie wczytanych danych */
      tmp->nast=NULL; /* jak na razie brak następnego */
      if(tail) tail->nast=tmp; /* jeżeli jest ostatni, to wstań za nim */
      else head=tmp; /* jeżeli nie ma to jesteś pierwszy */
      tail=tmp; /* skoro wstałeś do kolejki to jesteś ostatnim */
     }
   fclose(plik);
   for(tmp=head;tmp;tmp=tmp->nast) /* od głowy ; dopóki mamy kolejnego ; przejdź do następnego */
     {
      printf("%s %s %d\n",tmp->nazwisko,tmp->imie,tmp->wiek);
     }
   return 0;
  }
0

Dzięki wielkie, sporo się rozjaśniło. Jeszcze drobne 2 pytania.

  1. Chcę odwołać się do konkretnego pola, np. nazwisko. Czy jest różnica między:
dane.nazwisko
dane->nazwisko

Czy

->

używa się, gdy mamy do czynienia ze wskaźnikiem? ( wywnioskowałem z kodu )
2. Chciałem dodać nowe pole data ( data urodzenia ).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct Student
  {
   char nazwisko[15];
   char imie[15];
   char data[10];
   int wiek;
   struct Student *nast;
  };
 
int main()
  {
   struct Student dane, *tmp, *tail=NULL, *head=NULL; /* =NULL; -> inicjalizacja */
   FILE* plik=fopen("student.txt", "r");
   while(fscanf(plik, "%s %s %s %d", dane.nazwisko, dane.imie, dane.data, &dane.wiek)==4) /* dopóki udało się wczytać */
     {
      tmp=(struct Student*)malloc(sizeof(struct Student)); /* przydzielenie pamięci */
      *tmp=dane; /* przekopiowanie wczytanych danych */
      tmp->nast=NULL; /* jak na razie brak następnego */
      if(tail) tail->nast=tmp; /* jeżeli jest ostatni, to wstań za nim */
      	else head=tmp; /* jeżeli nie ma to jesteś pierwszy */
      tail=tmp; /* skoro wstałeś do kolejki to jesteś ostatnim */
     }
   fclose(plik);
   for(tmp=head; tmp; tmp=tmp->nast) /* od głowy ; dopóki mamy kolejnego ; przejdź do następnego */
     {
      printf("%s %s %s %d\n", tmp->nazwisko, tmp->imie, tmp->data, tmp->wiek);
     }
   return 0;
  }

Wszystko działa, tylko występuje problem przy wypisaniu, dokładnie taki:
user image
Po dacie ( zasadniczo w niej ) pojawia się dodatkowy znak.

EDIT: Problem zniknął, gdy zmieniłem:

struct Student
  {
   char nazwisko[15];
   char imie[15];
   char data[10];
   int wiek;
   struct Student *nast;
  };

na:

struct Student
  {
   char nazwisko[15];
   char imie[15];
   char data[11];
   int wiek;
   struct Student *nast;
  };

Ma to związek, z ostatnim elementem tablicy, którym jest '\0'?

1

Problem z pamięcią:

char data[11];
...
fscanf(plik, "%14s %14s %10s %d",...

Obiekt i wskaźnik to różne rzeczy:

struct Student dane,*tmp=&dane;
dane.wiek=1;
tmp->wiek=2;
(*tmp).wiek=3;
tmp[0].wiek=4;
0[tmp].wiek=5;

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