Problem z pętla wczytywania

0

Witam, problem polega na tym ze program normalnie zapisuje wpisane dane i je wyswietla lecz po zamknieciu i ponownym uruchomieniu wyswietla tylko i wyłacznie pierwsza pozycje z pliku. Co moze być przyczyną?```

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

// struktura glowna
struct wpis{
  char *nazwa;
  double *cena;
  float *ilosc;
  struct wpis *next;
}baza;

// wskaznik do struktury glownej
struct wpis *dodaj_wpis;
struct wpis *poczatek = NULL;
struct wpis *koniec = NULL;

// dodaje elementy struktury do pamieci
void nowy() {
  char t[20];
  double r[20];
 float g[10];

  dodaj_wpis = malloc(sizeof (baza));
  printf("Podaj nazwe: ");
  scanf("%s", t);

  dodaj_wpis->nazwa=malloc( sizeof(char) * strlen(t));
  strcpy( dodaj_wpis->nazwa, t );

  printf("Podaj cene: ");
  scanf("%s", r);

  dodaj_wpis->cena=malloc( sizeof(double) * strlen(r));
  strcpy( dodaj_wpis->cena, r );

  printf("Podaj ilosc: ");
  scanf("%s", g);

  dodaj_wpis->ilosc=malloc( sizeof(float) * strlen(g));
  strcpy( dodaj_wpis->ilosc, g );

  dodaj_wpis -> next = NULL;

  if (koniec == NULL)
        poczatek = koniec = dodaj_wpis;
  else {
        koniec->next = dodaj_wpis;
        koniec = dodaj_wpis;
  }
}

// wyswietla elementy struktury
void screen() {
  int lp;
  struct wpis *tmp;
  lp = 1;
  tmp = poczatek;
  if(poczatek == NULL)
  {
         printf("Baza danych jest pusta. Wprowadz dane.\n\n");
         return;
   }
//jeśli kod wykonuje się dalej, to baza nie jest pusta
  while(tmp != NULL)
 {
        printf("%d.\t%s\t%s\t%s\n", lp, tmp->nazwa, tmp->cena, tmp->ilosc);
        tmp = tmp -> next;
        lp++;

  }
}

// zapisuje dane z pamieci do pliku txt
void write1() {
  FILE* wp;

  wp = fopen("log.txt", "w");
  dodaj_wpis = poczatek;
  while(dodaj_wpis != NULL) {
        fprintf(wp, "%s", dodaj_wpis->nazwa);
        fprintf(wp, " %s", dodaj_wpis->cena);
        fprintf(wp, " %s\n", dodaj_wpis->ilosc);

        dodaj_wpis = dodaj_wpis -> next;
  }
  fclose(wp);
}

// wczytywanie danych z pliku txt
void load() {
  FILE* wp;
  char t[20];
  char r[20];
  char g[10];

  wp = fopen("log.txt", "r");
  if(wp != NULL){

        while(feof(wp)==0)
            break;
        {
          dodaj_wpis = malloc(sizeof (baza));

          fscanf(wp,"%s", t);

          dodaj_wpis->nazwa=malloc( sizeof(char) * strlen(t));
          strcpy( dodaj_wpis->nazwa, t );

          fscanf(wp,"%s", r);

          dodaj_wpis->cena=malloc( sizeof(char) * strlen(r));
          strcpy( dodaj_wpis->cena, r );

         fscanf(wp,"%s", g);

          dodaj_wpis->ilosc=malloc( sizeof(char) * strlen(g));
          strcpy( dodaj_wpis->ilosc, g );

          dodaj_wpis -> next = NULL;

          if (koniec == NULL)
                poczatek = koniec = dodaj_wpis;
          else {
                koniec->next = dodaj_wpis;
                koniec = dodaj_wpis;
          }

        }
        fclose(wp);
  }
else;
}

int main()
{
  int x, y;
  printf("================================================================================\n");
  printf("\t\t\t\tBAZA DANYCH\n");
  printf("================================================================================\n\n");

  printf("Nacisnij [enter] aby rozpoczac lub [q] aby zakonczyc\n");
  x = getch();
  load();
  if(x == 'q')
        NULL;
  else {
        while(x != EOF) {
          printf("MENU\t\t:::[W]yswietl | [D]odaj | [Q]uit:::\n");
          y = getch();
          if(y=='w')
                screen();
          else if(y == 'd')
                nowy();
          else if(y == 'q') {
                write1();
                break;
          }
          else printf("Niepoprawna opcja\n");
        }
  }
  system("PAUSE");
  return 0;
}

Wiem że wszystko zrobione na %s ale w ten sposob najlepiej mi to działa ;)

1

Twoja pętla wczytująca dane z pliku:

while(feof(wp)==0)
  break;
{
  ...
}
2

Przeanalizuj pod debuggerem i postaraj się dostarczyć MCVE: https://dsp.krzaq.cc/post/445/jak-zadawac-pytania-na-forum/

Na pewno dziwnie alokujesz pamięć:

  printf("Podaj cene: ");
  scanf("%s", r);

  dodaj_wpis->cena=malloc( sizeof(double) * strlen(r));
  strcpy( dodaj_wpis->cena, r );

O co chodzi z tym sizeof(double)*strlen(r)?

          dodaj_wpis->nazwa=malloc( sizeof(char) * strlen(t));
          strcpy( dodaj_wpis->nazwa, t );

Tu i we wszystkich podobnych przypadkach masz UB - alokujesz jeden bajt za mało - strlen zwraca długość napisu, ale bez kończącego go znaku zerowego.

1

Wprowadzasz zależności od trzech zmiennych globalnych, przez co śledzenie tego kodu to męczarnia. Zrób bez nich, to będzie łatwiej; Debugowałeś to w ogóle?

0

Cos pokombinuje, dziękuje

2

Zmienne globalne to samo zło i to jest tego przykład.
dodaj_wpis czemu jest globalna?
load() za dużo sam robi i dlatego nie ogarniasz problemu: otwiera plik, czyta dane, tworzy wpis, manipuluje na liście.

wpis.cena jest w końcu typu char* czy double*?

void LoadFromFile(FILE* f, List *list) {
  char name[20];
  double price;
  double amount;

  while (fscanf(f, "%19s %lf %lf", name, &price, &amount) == 3) {
      wpis *nowy = wpisCreateNew(name, price, amount);
      listAppend(list, nowy);
  }
}

void LoadFromFileName(const char *fileName, List *list)
{
    FILE* f = fopen(fileName, "r");
    if (f) {
        LoadFromFile(f, list);
        fclose(f);
    }
}
0

Udało sie wszystko ogarnać ;) wystarczyło usunąć break i dodac \n przy wczytywaniu ostatniego stringa aby wszsytko dobrze działało

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