Odczytywanie z pliku do struktury [C]

Odczytywanie z pliku do struktury [C]
B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

W ramach zaliczenia muszę napisać program realizujący kase fiskalną, mógłby mnie ktoś naprowadzić dlaczego nie chce wczytywać z pliku? W funkcji wczytaj program nie wchodzi w ogóle do pętli a według mnie powinien, specyfikatory przy while są chyba dobrze dobrane, nie wiem co leży, pozdrawiam :)

Kopiuj
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

struct produkt * wczytaj();
void zapisz(struct zakupione *kupno);
struct zakupione * trybkasy(struct produkt *zakupy);
void wyswietlprodukt(struct produkt *zakupy);
void wyswietlzakupy(struct zakupione *kupno);
void oczysc(struct zakupione * kupno);
struct produkt * przydzielpamiecproduktu(int val);
struct zakupione * przydzielpamieczakupiona(int val);
void oczysc1(struct produkt * produkty);

int main()
{
	struct produkt *nowy=NULL;
	struct zakupione *nowe=NULL;
	int spr,a;
	setlocale(LC_ALL,"polish");
	nowy=wczytaj();
	printf("Witaj!\nWybierz czynność:1.Wyświetlenie produktów\n2.Tryb kasy\n3.Jeśli chcesz wyjść wciśnij dowolną literę\nPodaj cyfrę:");
	while(scanf("%d",&spr)==1)
	{
		while(spr>3 || spr<1)
		{
		printf("Wprowadziłeś błędną cyfrę, wprowadź jeszcze raz!\n Podaj cyfrę:");
		a=scanf("%dwhile",&spr);
		}
		if(spr==1)
		{
			printf("Wybrałeś wyświetlenie!\n");
			wyswietlprodukt(nowy);
		}
		if(spr==2)
		{
			nowe=trybkasy(nowy);
			oczysc(nowe);
		}
		if(spr==3)
		{
			oczysc(nowe);
			oczysc1(nowy);
			printf("Żegnaj!");
			return 0;
		}
		printf("Witaj!\nWybierz czynność:1.Wyświetlenie produktów\n2.Tryb kasy\n3.Wyjście(lub podanie litery)\nPodaj cyfrę:");
	}
	if(nowe!=NULL)
		oczysc(nowe);
	if(nowy!=NULL)
		oczysc1(nowy);
	printf("Żegnaj!");
	return 0;
}
struct produkt
{
	char *nazwaproduktu;
	unsigned short *kodproduktu;
	float *cenaproduktu;
	char *oznaczenie;
	int ilosc;
};
struct zakupione
{
	char *nazwaproduktu;
	unsigned short *kodproduktu;
	float *cenaproduktu;
	float cena;
	float podatek;
	float reszta;
	int ilosc;
};
struct zakupione *trybkasy(struct produkt *zakupy)
{	
	struct zakupione *tmp=NULL;
	unsigned short kod;
	int a,i=0,j=0,spr,spr3,sztuka;
	float waga,cena,spr1,kwota;
	printf("Oto lista dostępnych artykułów");
	wyswietlprodukt(zakupy);
	for(;;)
	{	
		printf("Podaj kod produktu:\n");
		a=scanf("%hu",&kod);
		while(!a)
		{
			printf("Wpisałeś błędny kod! Podaj jeszcze raz!:\n");
			a=scanf("%hu",&kod);
		}
		for(i=0;i<=zakupy->ilosc;i++)
		{
			if(zakupy->kodproduktu[i]==kod)
			{
				printf("Podałeś poprawny kod!");
				break;
			}
			if(i==zakupy->ilosc)
			{
				printf("Podałeś błędny kod! Wprowadź jeszcze raz:\n");
				a=scanf("%hu",&kod);
				while(!a)
				{
					printf("Wpisałeś błędny kod! Podaj jeszcze raz!:\n");
					a=scanf("%hu",&kod);
				}
				i=0;
			}
		}
		tmp=przydzielpamieczakupiona(j);
		if(tmp==NULL)
		{
			printf("Błąd przydzielania pamięci!\n");
			return 0;
		}
		printf("Wybrałeś:%s\nCenaproduktu to:%f\n",zakupy->nazwaproduktu[i],zakupy->cenaproduktu[i]);
		if(zakupy->oznaczenie[i]=='S')
		{
			printf("Podaj ilość sztuk:\n");
			spr=scanf("%d",&sztuka);
			while(sztuka<0)
			{
				printf("Wprowadziłeś błędne dane!Podaj jeszcze raz:\n");
				spr=scanf("%d",&sztuka);
			}
			cena=sztuka*(zakupy->cenaproduktu[i]);
			tmp->cena=cena+(tmp->cena);
			tmp->nazwaproduktu[j]=zakupy->nazwaproduktu[i];
			tmp->cenaproduktu[j]=zakupy->cenaproduktu[i];
			tmp->kodproduktu[j]=zakupy->kodproduktu[i];
			j++;
		}
		if(zakupy->oznaczenie[i]=='W')
		{
			printf("Podaj wagę:\n");
			spr1=scanf("%f",&waga);
			while(waga<0)
			{
				printf("Wprowadziłeś błędne dane!Podaj jeszcze raz:\n");
				spr=scanf("%f",&waga);
			}
			cena=waga*(zakupy->cenaproduktu[i]);
			tmp->cena=cena+(tmp->cena);
			tmp->nazwaproduktu[j]=zakupy->nazwaproduktu[i];
			tmp->cenaproduktu[j]=zakupy->cenaproduktu[i];
			tmp->kodproduktu[j]=zakupy->kodproduktu[i];
			j++;
		}
		printf("Aby wybrać kolejny produkt wciśnij dowolną cyfrę, aby przerwać kupowanie wciśnij dowolną literę:\n");
		spr=scanf("%d",&spr3);
		if(!spr)
			break;
	}
	printf("Podaj kwotę otrzymaną od klienta w celu wydania reszty:\n");
	spr=scanf("%f",&kwota);
	while(spr==0 || kwota<0 || kwota-(tmp->cena)<0) // jeszcze wycofanie?
	{
		printf("Kwota została błędnie wprowadzona!Wprowadź jeszcze raz!");
		spr=scanf("%f",&kwota);
	}
	tmp->reszta=kwota-(tmp->cena);
	tmp->podatek=0.23*(tmp->cena);
	tmp->ilosc=j;
	wyswietlzakupy(tmp);
	zapisz(tmp);
	return tmp;
}
struct zakupione *przydzielpamieczakupiona(int val)
{
	struct zakupione *kupno;
	char *prt;
	float *prt1;
	unsigned short *prt2;
	kupno=(struct zakupione *)calloc(1,sizeof(struct zakupione));
	if(kupno==NULL)
	{
		printf("Błąd przydzielania pamięci!\n");
		return 0;
	}
	prt=(char*)realloc((kupno->nazwaproduktu),(val+1)*sizeof(char));
	if(prt==NULL)
	{
		printf("Błąd przydzielania pamięci!");
		free(kupno);
		return 0;
	}
	prt1=(float*)realloc((kupno->cenaproduktu),(val+1)*sizeof(float));
	if(prt1==NULL)
	{
		printf("Błąd przydzielania pamięci!");
		free(prt);
		free(kupno);
		return 0;
	}
	prt2=(unsigned short*)realloc((kupno->kodproduktu),(val+1)*sizeof(unsigned short));
	if(prt2==NULL)
	{
		printf("Błąd przydzielania pamięci!");
		free(prt);
		free(prt1);
		free(kupno);
		return 0;
	}
	kupno->nazwaproduktu=prt;
	kupno->cenaproduktu=prt1;
	kupno->kodproduktu=prt2;
	return(kupno);
}
struct produkt *przydzielpamiecproduktu(int val)
{
	struct produkt *kupno;
	char *prt1,*prt2;
	float *prt3;
	unsigned short *prt4;
	kupno=(struct produkt *)calloc(1,sizeof(struct produkt));
	if(kupno==NULL)
	{
		printf("Błąd przydzielania pamięci!\n");
		return 0;
	}
	prt1=(char*)realloc((kupno->nazwaproduktu),(val+1)*sizeof(char));
	if(prt1==NULL)
	{
		printf("Błąd przydzielania pamięci!");
		free(kupno);
		return 0;
	}
	prt2=(char*)realloc((kupno->oznaczenie),(val+1)*sizeof(char));
	if(prt2==NULL)
	{
		printf("Błąd przedzielania pamięci!");
		free(prt1);
		free(kupno);
		return 0;
	}
	prt3=(float*)realloc((kupno->cenaproduktu),(val+1)*sizeof(float));
	if(prt3==NULL)
	{
		printf("Błąd przydzielania pamięci!");
		free(prt1);
		free(prt2);
		free(kupno);
		return 0;
	}
	prt4=(unsigned short*)realloc((kupno->kodproduktu),(val+1)*sizeof(unsigned short));
	if(prt4==NULL)
	{
		printf("Błąd przydzielania pamięci!");
		free(prt1);
		free(prt2);
		free(prt3);
		free(kupno);
		return 0;
	}
	kupno->nazwaproduktu=prt1;
	kupno->oznaczenie=prt2;
	kupno->cenaproduktu=prt3;
	kupno->kodproduktu=prt4;
	return(kupno);
}
struct produkt *wczytaj()
{
	struct produkt *tmp=NULL;
	int mem_size=0,i=0;
	FILE *plik;
	plik=fopen("produkty.csv","rt");
	if(plik==NULL)
	{
		printf("Błąd otwarcia pliku!\n");
		return 0;
	}
	printf("Przydzielam pamięć!");
	tmp=przydzielpamiecproduktu(mem_size);
	printf("Przydzieliłem!\n");
	if(tmp==NULL)
	{
		printf("Pamięć błędnie przydzielona!");
		fclose(plik);
		oczysc1(tmp);
		return 0;
	}
	mem_size++;
	while((fscanf(plik,"%f;%hu;%c;%s\n",&tmp->cenaproduktu[i],&tmp->kodproduktu[i],&tmp->oznaczenie[i],&tmp->nazwaproduktu[i]))==4)
	{	
		printf("Czy byłem w while?");
		if(tmp->oznaczenie[i]!='S' || tmp->oznaczenie[i]!='W')
		{
			printf("Błędne oznaczenie ilości/wagi!\n");
			return 0; 
		}
		tmp=przydzielpamiecproduktu(mem_size);
		if(tmp==NULL)
		{
			printf("Pamięć błędnie przydzielona!\n");
			fclose(plik);
			oczysc1(tmp);
			return 0;
		}
		mem_size++;
		i++;
	}
	printf("Pomijam\n");
	tmp->ilosc=(i);
	fclose(plik);
	printf("Produkty zostały pomyślnie wczytane!\nIlość odczytanych produktów wynosi %d!",tmp->ilosc);
	return(tmp);
}
void zapisz(struct zakupione *kupno)
{
	 FILE *plik;
	 int i=0;
	 plik=fopen("zakupione.csv","wt");
	 if(plik==NULL)
	 {
		 printf("Błąd otwarcia pliku!\n");
		 return;
	 }
	 for(i=0;i<(kupno->ilosc);i++)
		 fprintf(plik,"%s;%hu;%f\n",kupno->nazwaproduktu[i],kupno->kodproduktu[i],kupno->cenaproduktu[i]);
	 fprintf(plik,"%f\n %f\n %f\n",kupno->cena,kupno->reszta,kupno->podatek);
	 printf("Paragon został pomyślnie zapisany!\n");
	 fclose(plik);
}
void wyswietlprodukt(struct produkt*zakupy)
{  
	int i;
	printf("%f",zakupy->cenaproduktu[2]);
	printf("Oto lista produktów:\n");
	for(i=0;i<(zakupy->ilosc);i++)
	{	
		printf("%f",zakupy->cenaproduktu[i]);
		printf("%s %hu %f\n",zakupy->nazwaproduktu[i],zakupy->kodproduktu[i],zakupy->cenaproduktu[i]);	
	}
	printf("Produkty zostały wyświetlone!\n");
}
void wyswietlzakupy(struct zakupione *kupno)
{
	int i;
	printf("Oto paragon:\n");
	for(i=0;i<(kupno->ilosc);i++)
		printf("%s %hu %f\n",kupno->nazwaproduktu[i],kupno->kodproduktu[i],kupno->cenaproduktu[i]);
	printf("Cena:%fzł\nPodatek:%fzł\nReszta:%fzł\n",kupno->cena,kupno->podatek,kupno->reszta);
	printf("Paragon został wyświetlony\n");
}
void oczysc(struct zakupione *kupno)
{
	if(kupno==NULL)
		return;
	
	
		if(kupno->nazwaproduktu!=NULL)
			free(kupno->nazwaproduktu);
		if(kupno->cenaproduktu!=NULL)
			free(kupno->cenaproduktu);
		if(kupno->kodproduktu!=NULL)
			free(kupno->kodproduktu);
		free(kupno);
	
}
void oczysc1(struct produkt *produkty)
{
	if(produkty==NULL)
		return;
		
		if(produkty->nazwaproduktu!=NULL)
			free(produkty->nazwaproduktu);
		if(produkty->cenaproduktu!=NULL)
			free(produkty->cenaproduktu);
		if(produkty->kodproduktu!=NULL)
			free(produkty->kodproduktu);
		if(produkty->oznaczenie!=NULL);
			free(produkty->oznaczenie);
		free(produkty);
	
}
 
edytowany 1x, ostatnio: Bra5i
szweszwe
  • Rejestracja:ponad 11 lat
  • Ostatnio:dzień
  • Lokalizacja:Kraków
  • Postów:1694
0

Wygląda na to, że w while jest jednak coś nie tak. Po usunięciu kilku rzeczy weszło mi do pętli. Może masz też inaczej zapisane dane w pliku niż format podczas czytania?

B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

W czterech kolumnach kolejno mam wpisane Makaron 325 16,89 W - czyli zgodnie łańcuch, unsigned short, float i char czyli oznacznie

szweszwe
Ja przy scanfie widzę średniki.
B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

Średniki aby przechodzić między kolejnymi kolumnami?

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

W pliku masz zapisane:
Makaron;325;16,89;W
W związku z czym przy odczycie masz cały wiersz wczytany wg formatu %s
Zapisuj wg formatu: printf("%u %f %c %s\n"...
Wczytuj wg formatu: scanf(" %u %f %c "... plus fgtets


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

Czyli jak mam średniki to on traktuje całe wiersz jako jeden łańcuch? Fgets czyta dopóki nie natrafi na znak końca lini, jak to z nim rozwiązać żeby rozróżniał moje cztery wartości i przypisywał je od razu do moich tablic?
Sorry Panowie ale człowiek sie uczy całe życie i wolę się dopytać i wyjść na głupiego niż sam dochodzić do tego przez 30 minut :)

edytowany 1x, ostatnio: Bra5i
n0name_l
  • Rejestracja:ponad 12 lat
  • Ostatnio:ponad 4 lata
  • Postów:2412
0
Kopiuj
void read_to_character(char* buffer, char character) {
    char c;
    int i=0;
    while((c = getchar()) != character) {
        buffer[i++] = c;
    }
    buffer[i] = 0;
}

http://ideone.com/OzYrgV

edytowany 2x, ostatnio: n0name_l
B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

Panowie szczerze to trochę nie nadążam za wami, w programie poprawiłem jeszcze parę rzeczy(uaktualniłem program u góry), które leżały ale dalej pozostaje problem z wczytaniem, na laboratorium odczytywaliśmy z pliku .csv przy pomocy średników ale to były wartości typu float, a tutaj jak sobie sprawdzałem to faktycznie on całą linijkę wczytuje do łańcucha od razu a gdy przychodzi czas na resztę while się wysypuje i dalej nie idzie. Jak to ruszyć? Tutaj kolega wyżej wrzucił mi funkcje, ale jak ją ugryźć(jeszcze sie uczę także proszę o wyrozumienie).. Prosiłbym o pomoc bo jutro chciałbym oddać ten program bo jednak reszta egzaminów atakuje :)

_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0
Bra5i napisał(a):

Jak to ruszyć?
Normalnie użyj tej funkcji.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0
_13th_Dragon napisał(a):
Bra5i napisał(a):

Jak to ruszyć?
Normalnie użyj tej funkcji.

no ale nie rozumiem, dlatego pytam. Getchar odczyta cały łańcuch i wpisze go do tablicy po czym jak trafi na średnik wyjdzie z funkcji, następnie wartości unsigned short, float i char odczytuję normalnie podając średnik? Gdy odczytam ostatnią wartość w tej linijce czyli &char->oznaczenie znowu wywołuję funkcję odczytując do momentu średnika(czyli w pętli) ?

edytowany 1x, ostatnio: Bra5i
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

Masz dwa warianty:

  1. wg tego co ja zaproponowałem: przenieś napis na koniec i nie ma problemów
  2. wg tego co @n0name_l zaproponował, napis wczytujesz funkcją resztę normalnie scanf'em

Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

Zmieniłem wczytaj w ten sposób i dalej nie czyta..

Kopiuj
 struct produkt *wczytaj()
{
	struct produkt *tmp=NULL;
	char *result;
	int mem_size=0,i=0;
	FILE *plik;
	plik=fopen("produkty.csv","rt");
	if(plik==NULL)
	{
		printf("Błąd otwarcia pliku!\n");
		return 0;
	}
	printf("Przydzielam pamięć!\n");
	tmp=przydzielpamiecproduktu(mem_size);
	printf("Przydzieliłem!\n");
	if(tmp==NULL)
	{
		printf("Pamięć błędnie przydzielona!");
		fclose(plik);
		oczysc1(tmp);
		return 0;
	}
	mem_size++;
	while((fscanf(plik,"%f %hu %c",&tmp->cenaproduktu[i],&tmp->kodproduktu[i],&tmp->oznaczenie[i]))==3)
	{
		result=fgets(tmp->nazwaproduktu,sizeof(tmp->nazwaproduktu),plik);
		if(result==NULL)
		{
			printf("Błąd odczytu!\n");
			return 0;
		}
		if(tmp->oznaczenie[i]!='S' || tmp->oznaczenie[i]!='W')
		{
			printf("Błędne oznaczenie ilości/wagi!\n");
			return 0; 
		}
		if(feof(plik)==0)
		{
			printf("Koniec pliku!");
			break;
		}
		tmp=przydzielpamiecproduktu(mem_size);
		if(tmp==NULL)
		{
			printf("Pamięć błędnie przydzielona!\n");
			fclose(plik);
			oczysc1(tmp);
			return 0;
		}
		mem_size++;
		i++;
	}
	printf("Pomijam\n");
	tmp->ilosc=(i);
	fclose(plik);
	printf("Produkty zostały pomyślnie wczytane!\nIlość odczytanych produktów wynosi %d!",tmp->ilosc);
	return(tmp);
}
}
edytowany 2x, ostatnio: Bra5i
szweszwe
Mi pomogła zamiana %c z %hu miejscami przy wczytywaniu. Spradź też jaką wartość ma 'i' gdy ją przypisyjesz do ilości na końcu.
B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

Poradziłem sobie już z tym zagadnieniem, teraz już mi wszystko czyta, ale jak to bywa.. code & fix..
Mój kolejny problem leży w tym,że z próbowałem zapisywać nazwy do tablicy znaków, więc teraz walczę z tablicą łańcuchów, mam ją dwuwymiarową, i deklaruję funkcję w ten sposób, co wy na to:

Kopiuj
struct produkt *przydzielpamiecproduktu(struct produkt *kupno,int val,float cena,unsigned short kod,int oznaczenie, char *buff)
{	
	char **prt1;
	int *prt2;
	float *prt3;
	unsigned short *prt4;
	int i,size;
	size=strlen(buff);
	if(kupno==NULL)
	{
		kupno=(struct produkt *)calloc(1,sizeof(struct produkt));
		if(kupno==NULL)
		{
			printf("Błąd przydzielania pamięci!\n");
			return 0;
		}
	}
	prt1=(char**)realloc((kupno->nazwaproduktu),(val+1)*sizeof(char*));
	if(prt1==NULL)
	{
		printf("Błąd przydzielania pamięci!");
		free(kupno);
		return 0;
	}
	for(i=0;i<size;i++)
	{
		prt1[i]=(char*)realloc((kupno->nazwaproduktu),(size)*sizeof(char)));
		if(prt1[i]==NULL)
		{
			printf("Błąd przydzielania pamięci!\n");
			free(kupno);
			return 0;
		}
	}
	prt2=(int*)realloc((kupno->oznaczenie),(val+1)*sizeof(int));
	if(prt2==NULL)
	{
		printf("Błąd przedzielania pamięci!");
		free(prt1);
		free(kupno);
		return 0;
	}
	prt3=(float*)realloc((kupno->cenaproduktu),(val+1)*sizeof(float));
	if(prt3==NULL)
	{
		printf("Błąd przydzielania pamięci!");
		free(prt1);
		free(prt2);
		free(kupno);
		return 0;
	}
	prt4=(unsigned short*)realloc((kupno->kodproduktu),(val+1)*sizeof(unsigned short));
	if(prt4==NULL)
	{
		printf("Błąd przydzielania pamięci!");
		free(prt1);
		free(prt2);
		free(prt3);
		free(kupno);
		return 0;
	}
	kupno->nazwaproduktu=prt1;
	for(i=0;i<size;i++)
	{
		kupno->nazwaproduktu[val][i]=buff[i];
	}
	kupno->oznaczenie=prt2;
	kupno->oznaczenie[val]=oznaczenie;
	kupno->cenaproduktu=prt3;
	kupno->cenaproduktu[val]=cena;
	kupno->kodproduktu=prt4;
	kupno->kodproduktu[val]=kod;
	return(kupno);
}
 
edytowany 1x, ostatnio: Bra5i
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
1

Może przerób całość dopóki nie zabrnąłeś zbyt daleko.
Twoja struktura powinna wyglądać następująco:

Kopiuj
struct produkt
  {
   char *nazwa;
   int oznaczenie;
   unsigned short kod;
   float cena;
   int ilosc;
  };

struct produkty
  {
   struct produkt *tablica;
   unsigned ilosc;
  };

void przydzielpamiecproduktu(struct produkty *sklep,int ilosc,float cena,unsigned short kod,int oznaczenie,const char *nazwa)
  {
   sklep->tablica=(struct produkt *)realloc(sklep->tablica,sklep->ilosc*sizeof(struct produkt));
   sklep->tablica[sklep->ilosc].nazwa=strdup(nazwa);
   sklep->tablica[sklep->ilosc].ilosc=ilosc;
   sklep->tablica[sklep->ilosc].cena=cena;
   sklep->tablica[sklep->ilosc].kod=kod;
   sklep->tablica[sklep->ilosc].oznaczenie=oznaczenie;
   ++sklep->ilosc;
  }

Zauważ o ile jest prostsze.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon
B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

Dzięki wielkie! Nie wpadłem na to, czlowiek się uczy całe życie!:)

B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

No więc tak, sprawdzałem debugger'em i problem leży w funkcjach oczyszczających bo nie robią tego jak powinny, mógłby ktoś skontrolować jak to powinno wyglądać żeby z pamięcią się cuda nie działy? z góry dziękuje!

Kopiuj
 #define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

struct produkt
  {
   char *nazwa;
   int oznaczenie;
   unsigned short kod;
   float cena;
  };
struct produkty
  {
   struct produkt *tablica;
   int ilosc;
  };
struct paragon
{
	char *nazwap;
	unsigned short kodp;
	float cenap;
	int sztuka;
	float waga;
	int oznaczenie;
};
struct calyparagon
{
	struct paragon *tab;
	int iloscp;
	float cena_end;
	float podatek;
	float reszta;
};
void zapisz(struct calyparagon *paragon);
struct produkty *przydzielpamiecproduktu(struct produkty *sklep,int mem_size,float cena,unsigned short kod,int oznaczenie,const char *nazwa);
struct produkty *wczytaj();
void wyswietl(struct produkty *sklep);
void wyswietl1(struct calyparagon *paragon);
struct calyparagon *kasa(struct produkty *sklep);
struct calyparagon *przydzielpamiec(struct calyparagon *zakupione,struct produkty *sklep,int val,int mem_size);
void oczysc(struct produkty *sklep);
void oczysc1(struct calyparagon *zakupione);

int main()
{
	struct produkty *listaproduktow=NULL;	
	struct calyparagon *listazakupionych=NULL;
	setlocale(LC_ALL,"polish");
	printf("Witaj w kasie!\n");
	listaproduktow=wczytaj();
	listazakupionych = kasa(listaproduktow);
	zapisz(listazakupionych);
	wyswietl1(listazakupionych);
	printf("Przeszedłem przez wyświetl\n");
	oczysc(listaproduktow);
	printf("Przeszedłem przez oczyść\n");
	oczysc1(listazakupionych);
	system("PAUSE");
	return 0;
}
struct produkty *wczytaj()
{
	struct produkty *sklep=NULL;
	float cena;
	int oznaczenie,i=0,mem_size=0;
	unsigned short kod;
	char nazwa[100];
	FILE *plik;
    plik=fopen("produkty.txt","rt");
    if(plik==NULL)
    {
		printf("Błąd otwarcia pliku!\n");
        return 0;
    }
	while((fscanf(plik,"%f%hu%d%s",&cena,&kod,&oznaczenie,&nazwa))==4)
	{
		if(oznaczenie!=1 && oznaczenie!=2)
        {
			printf("Błędne oznacznie!\n");
            return 0;
        }
		sklep=przydzielpamiecproduktu(sklep,mem_size,cena,kod,oznaczenie,nazwa);
		if(sklep==NULL)
		{
			printf("Pamięć błędnie przydzielona!\n");
			fclose(plik);
			return 0;
		}
		mem_size++;
		i++;
	}
	sklep->ilosc=i;
	fclose(plik);
	printf("Liczba produktów dostępnym w bazie:%d\n",i);
	return (sklep);
}
void zapisz(struct calyparagon *zakupione)
{
	 FILE *plik;
	 int i=0;
	 plik=fopen("paragon.txt","wt");
	 if(plik==NULL)
	 {
		 printf("Błąd otwarcia pliku!\n");
		 return;
	 }
	 for(i=0;i<=(zakupione->iloscp);i++)
	 {
		 if(i==0)
			 fprintf(plik,("Nazwa produktu Kod Produktu Cena Produktu Waga/Ilość\n"));
		 if(zakupione->tab[i].oznaczenie==1)
			 fprintf(plik,("%s %hu %f %d\n"),zakupione->tab[i].nazwap,zakupione->tab[i].kodp,zakupione->tab[i].cenap,zakupione->tab[i].sztuka);
		 else
			 fprintf(plik,("%s %hu %f %f\n"),zakupione->tab[i].nazwap,zakupione->tab[i].kodp,zakupione->tab[i].cenap,zakupione->tab[i].waga);
	 }
	 fprintf(plik,"Cena:%f Reszta:%f Podatek:%f",zakupione->cena_end,zakupione->reszta,zakupione->podatek);
	 printf("Paragon został pomyślnie zapisany!\n");
	 fclose(plik);
}
struct produkty *przydzielpamiecproduktu(struct produkty *sklep,int mem_size,float cena,unsigned short kod,int oznaczenie, const char *nazwa)
{
	if(sklep==NULL)
	{
		sklep=(struct produkty *)calloc(1,sizeof(struct produkty));
		if(sklep==NULL)
		{
			printf("Błąd przydzielania pamięci!\n");
			return 0;
		}
	}
	sklep->tablica=(struct produkt *)realloc(sklep->tablica,(mem_size+1)*sizeof(struct produkt));
	if(sklep->tablica==NULL)
	{
		printf("Błąd przydzielania pamięci!\n");
		return 0;
	}
    sklep->tablica[mem_size].nazwa=strdup(nazwa);
    sklep->tablica[mem_size].cena=cena;
    sklep->tablica[mem_size].kod=kod;
    sklep->tablica[mem_size].oznaczenie=oznaczenie;
	sklep->ilosc=mem_size;
	return(sklep);
}
void wyswietl(struct produkty *sklep)
{
	int i;
	printf("Produkty:\n");
	if(sklep==NULL)
	{
		printf("Nie ma co wyświetlać!\n");
		return;
	}
	for(i=0;i<sklep->ilosc;i++)
		printf("Nazwa produktu:%s,Cena produktu: %.2f,Kod produktu: %d\n",sklep->tablica[i].nazwa,sklep->tablica[i].cena,sklep->tablica[i].kod);
	printf("Produkty zostały wyświetlone!\n");
}
void wyswietl1(struct calyparagon *zakupione)
{
	int i;
	printf("Paragon:\n");
	if(zakupione==NULL)
	{
		printf("Nie ma co wyświetlać");
		return;
	}
	for(i=0;i<=zakupione->iloscp;i++)
	{
		if(zakupione->tab[i].oznaczenie==1)
			printf("Nazwa produktu:%s,Cena produktu: %.2f,Kod produktu: %d,Ilość sztuk:%d\n",zakupione->tab[i].nazwap,zakupione->tab[i].cenap,zakupione->tab[i].kodp,zakupione->tab[i].sztuka);
		else
			printf("Nazwa produktu:%s,Cena produktu: %.2f,Kod produktu: %d,Waga:%.2f\n",zakupione->tab[i].nazwap,zakupione->tab[i].cenap,zakupione->tab[i].kodp,zakupione->tab[i].waga);
	}
	printf("Do zapłaty:%f\nReszta:%f\nPodatek:%f\n",zakupione->cena_end,zakupione->reszta,zakupione->podatek);
	printf("Produkty zostały wyświetlone!\n");
}
struct calyparagon *kasa(struct produkty *sklep)
{
	struct calyparagon *zakupione=NULL;
	unsigned short kod;
	int i,j=0,spr,spr1,spr2,spr3,sztuka;
	float waga,cenaall=0,kwota;
	wyswietl(sklep);
	printf("Podaj kod wybranego produktu:\n");
	spr=scanf("%hu",&kod);
	for(;;)
	{
		for(i=0;i<=sklep->ilosc;i++)
		{
			while(!spr)
			{
				printf("Podałeś błędny kod!Podaj raz jeszcze:\n");
				spr=scanf("%hu",&kod);
			}
			if(i==sklep->ilosc)
			{
				printf("Podałeś błędny kod! Podaj raz jeszcze:\n");
				spr=scanf("%hu",&kod);
				i=0;
			}
			if(sklep->tablica[i].kod==kod)
			{
				printf("Wybrany przez Ciebie produkt to: %s, jego cena to %f\n",sklep->tablica[i].nazwa,sklep->tablica[i].cena);
				if(sklep->tablica[i].oznaczenie==1)
				{
					printf("Podaj ilość sztuk towaru:\n");
					spr1=scanf("%d",&sztuka);
					while(!spr1 || sztuka<0)
					{
						printf("Podałeś błędną ilość sztuk towaru!Podaj jeszcze raz:\n");
						spr1=scanf("%d",&sztuka);
					}
					fflush(stdin);
					cenaall=cenaall+sztuka*(sklep->tablica[i].cena);
					zakupione=przydzielpamiec(zakupione,sklep,i,j);
					zakupione->tab[j].sztuka=sztuka;
					zakupione->tab[j].waga=0;
					zakupione->tab[j].oznaczenie=sklep->tablica[i].oznaczenie;
					j++;
				}
				else
				{
					printf("Podaj wagę towaru:\n");
					spr2=scanf("%f",&waga);
					while(!spr2 || waga<0)
					{
						printf("Podałeś błędną wagę towaru!Podaj jeszcze raz:\n");
						spr=scanf("%f",&waga);
					}
					cenaall=cenaall+waga*(sklep->tablica[i].cena);
					zakupione=przydzielpamiec(zakupione,sklep,i,j);
					zakupione->tab[j].waga=waga;
					zakupione->tab[j].sztuka=0;
					zakupione->tab[j].oznaczenie=sklep->tablica[i].oznaczenie;
					j++;
				}
				break;
			}
		}
		printf("Podaj kod kolejnego artykułu(podanie dowolnej litery spowoduje przerwanie kupowania):\n");
		spr=scanf("%hu",&kod);
		if(!spr)
			break;
	}
	zakupione->cena_end=cenaall;
	zakupione->podatek=0.23*cenaall;
	printf("Kwota do zapłaty:%f\n",zakupione->cena_end);
	printf("Podaj kwotę otrzymaną od klienta:\n");
	fflush(stdin);
	spr3=scanf("%f",&kwota);
	while(!spr3 || kwota<zakupione->cena_end)
	{
		printf("Podałeś złą kwotę!");
		spr3=scanf("%f",&kwota);
	}
	zakupione->reszta=kwota-zakupione->cena_end;
	printf("Reszta wynosi:%f\n",zakupione->reszta);
	return(zakupione);
}		
struct calyparagon *przydzielpamiec(struct calyparagon *zakupione,struct produkty *sklep,int val,int mem_size)
{
	if(zakupione==NULL)
	{
		zakupione=(struct calyparagon *)calloc(1,sizeof(struct calyparagon));
		if(zakupione==NULL)
		{
			printf("Błąd przydzielania pamięci!\n");
			return 0;
		}
	}
	zakupione->tab=(struct paragon *)realloc(zakupione->tab,(mem_size+1)*sizeof(struct paragon));
	if(zakupione->tab==NULL)
	{
		printf("Błąd przydzielania pamięci!\n");
		free(zakupione);
		return 0;
	}
	zakupione->tab[mem_size].nazwap=sklep->tablica[val].nazwa;
	zakupione->tab[mem_size].cenap=sklep->tablica[val].cena;
	zakupione->tab[mem_size].kodp=sklep->tablica[val].kod;
	zakupione->iloscp=mem_size;
	return(zakupione);
}
void oczysc(struct produkty *sklep)
{
	if(sklep==NULL)
		return;
	if(sklep->tablica!=NULL)
	{
		if(sklep->tablica->nazwa)
			free(sklep->tablica->nazwa);
		free(sklep->tablica);
	}
	free(sklep);	
}
void oczysc1(struct calyparagon *zakupione)
{	
	if(zakupione==NULL)
		return;
	if(zakupione->tab!=NULL)
	{
		if(zakupione->tab->nazwap)
			free(zakupione->tab->nazwap);
		free(zakupione->tab);
	}
	free(zakupione);
}
		



		


szweszwe
Czym się to objawia?
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:3 miesiące
0

Zacznij od uproszczenia kodu.
Zauważ że paragon to lista produktów więc niczym się nie powinien różnić od listy produktów, pola cena końcowa, podatek i reszta mogą zostać puste, albo też wypełniane podczas sprzedaży.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

Objawia się takim komunikatem na koniec:

Kopiuj
"Windows has triggered a breakpoint in Newww.exe.

This may be due to a corruption of the heap, which indicates a bug in Newww.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while Newww.exe has focus.

The output window may have more diagnostic information."
B5
  • Rejestracja:około 11 lat
  • Ostatnio:około 11 lat
  • Postów:12
0

Problem leżał ze zwalnianiem większej ilości pamięci niż była zadeklarowana

Można usunąć :)

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)