Hi,
das habe ich auch schon gelesen und auch den code von Prof Scheibls
001 //A03Sa : Einsprungpunkt fuer die Konsolenanwendung.
002 //
003 //Einfache Verwaltung fuer Artikel mit sequenzieller Datei
004 // dazu Heapverwaltung mit selbstgeschriebener Auflistung
005
006 #include <stdio.h> //fuer: FILE,stdin,fclose,feof,fgets,fopen,fprintf,printf
007 #include <stdlib.h> // atof, atoi,realloc,system
008 #include <conio.h> // getch
009 #include <string.h> // strlen
010 #include <malloc.h> // _msize,_HEAPOK...,_HEAPINFO,_heapcheck...
011
012 #define MITBEDARFSINFO
013 //#define MITHEAPINFO
014
015 bool bExterneDatei=false; //global
016
017 typedef char tZeile[80+1];
018 typedef struct Artikel tArtikel;
019
020 struct Artikel {
021 long ArtNr;
022 tZeile Name;
023 double Preis;
024 }; //struct Artikel
025
026 //Vorwaertsdeklarationen
027 //Rueckgabewerte void * muessen gecastet werden
028 // Rueckgabeparameter mit * werden veraendert
029 void zeigeMenue();
030 long eingebeArtikel(struct Artikel **,long *); //so
031 long ladeDatei(tArtikel **,long *); //oder so
032 long pruefeHeap(void);
033 long speichereDatei(struct Artikel *,long);
034 void zeigeHeapbelegung(void);
035 void zeigeListe(struct Artikel *,long);
036
037 long eingebeArtikel(struct Artikel **ppArtikel,long *pAnzahl) {
038 //Da realloc moeglicherweise den Speicherblock verschiebt,
039 // muss der neue Zeiger darauf als Referenz uebergeben werden
040 tZeile Zeile;
041 if (!(*ppArtikel=(Artikel*)realloc(*ppArtikel,(*pAnzahl+1)*sizeof(struct Artikel)))) {
042 printf("Speichermangel!\n");
043 return -1;
044 } //if
045 printf("Eingabe Artikel Nr. %3d:\n",*pAnzahl+1);
046 printf("------------------------\n");
047 printf("Artikel Nr.: ");
048 fgets(Zeile,sizeof(Zeile),stdin);
049 (*ppArtikel)[*pAnzahl].ArtNr=atol(Zeile);
050 printf("Name.......: ");
051 fgets((*ppArtikel)[*pAnzahl].Name,sizeof(Zeile),stdin);
052 (*ppArtikel)[*pAnzahl].Name[strlen((*ppArtikel)[*pAnzahl].Name)-1]='\0';
053 printf("Preis......: ");
054 fgets(Zeile,sizeof(Zeile),stdin);
055 (*ppArtikel)[*pAnzahl].Preis=atof(Zeile);
056 (*pAnzahl)++;
057 return 0;
058 } //eingebeArtikel
059
060 long ladeDatei(struct Artikel **ppArtikel,long *pAnzahl) {
061 //haengt den Inhalt einer Datei an die Artikelliste an
062 if (!bExterneDatei) {
063 FILE *fDatei;
064 tZeile Zeile;
065 if (fDatei=fopen("artikel.txt","r")) {
066 fgets(Zeile,sizeof(Zeile),fDatei); //Vorlesen einer Zeile
067 while (!feof(fDatei)) {
068 *ppArtikel=(Artikel*)realloc(*ppArtikel,(*pAnzahl+1)*sizeof(struct Artikel));
069 #ifdef MITBEDARFSINFO
070 printf("Die %d Artikel belegen %d Bytes!\n",*pAnzahl+1,_msize(*ppArtikel));
071 system("Pause");
072 #endif
073 #ifdef MITHEAPINFO
074 //Mit jedem Datensatz reduziert sich der freie Bereich
075 pruefeHeap();
076 zeigeHeapbelegung();
077 system("Pause");
078 #endif
079 if (!(*ppArtikel)) {
080 printf("Speichermangel\n");
081 return -1;
082 } //if
083 (*ppArtikel)[*pAnzahl].ArtNr=atoi(Zeile);
084 fgets((*ppArtikel)[*pAnzahl].Name,sizeof(Zeile),fDatei);
085 (*ppArtikel)[*pAnzahl].Name[strlen((*ppArtikel)[*pAnzahl].Name)-1]='\0';
086 fgets(Zeile,sizeof(Zeile),fDatei);
087 (*ppArtikel)[*pAnzahl].Preis=atof(Zeile);
088 (*pAnzahl)++;
089 fgets(Zeile,sizeof(Zeile),fDatei); //Nachlesen
090 } //while
091 bExterneDatei=true;
092 //Einsatz von fseek und ftell
093 fseek(fDatei,0L,SEEK_END);
094 printf("Dateilaenge %d\n",ftell(fDatei));
095 fclose(fDatei);
096 } else {
097 return -1;
098 } //if
099 } //if
100 return 0;
101 } //ladeDatei
102
103 long pruefeHeap(void) {
104 //Hilfsfunktion: prueft den Heap
105 int heapStatus;
106 heapStatus=_heapchk();
107 switch(heapStatus) {
108 case _HEAPOK:
109 printf("OK - Heap ist in Ordnung\n" );
110 break;
111 case _HEAPEMPTY:
112 printf("OK - leerer Heap\n" );
113 break;
114 case _HEAPBADBEGIN:
115 printf("FEHLER - am Heapanfang!\n" );
116 break;
117 case _HEAPBADNODE:
118 printf("FEHLER - falscher Knoten im Heap\n" );
119 break;
120 } //switch
121 return heapStatus;
122 } //pruefeHeap
123
124 long speichereDatei(struct Artikel *pArtikel,long nAnzahl) {
125 FILE *fDatei;
126 if (bExterneDatei) {
127 fDatei=fopen("artikel.txt","w");
128 } else if (!bExterneDatei) {
129 fDatei=fopen("artikel.txt","a+");
130 } else {
131 printf("Fehler beim Speichern der Datei!");
132 return -1;
133 } //if
134 if (NULL!=fDatei) {
135 long nI;
136 for(nI=0;nI<nAnzahl;nI++) {
137 fprintf(fDatei,"%d\n",pArtikel[nI].ArtNr);
138 fprintf(fDatei,"%s\n",pArtikel[nI].Name);
139 fprintf(fDatei,"%lf\n",pArtikel[nI].Preis);
140 } //for
141 printf("Daten wurden gesichert\n");
142 bExterneDatei=true;
143 system("PAUSE"); //Aufruf eines CMD-Kommandos
144 } else {
145 printf("Datei "artikel.txt" existiert nicht!\n");
146 return -1;
147 } //if
148 return 0;
149 } //speichereDatei
150
151 void zeigeHeapbelegung(void) {
152 _HEAPINFO hInfo;
153 int heapStatus;
154 hInfo._pentry=NULL; //Element der Struktur _HEAPINFO
155 while ((heapStatus=_heapwalk(&hInfo))==_HEAPOK) {
156 printf("%6s Block an %Fp der Laenge %4.4X\n",(hInfo._useflag==_USEDENTRY ? "BELEGT":"FREI" ),hInfo._pentry,hInfo._size);
157 } //while
158
159 switch(heapStatus) {
160 case _HEAPEMPTY:
161 printf("OK - leerer Heap\n");
162 break;
163 case _HEAPEND:
164 printf("OK - Heap-Ende\n");
165 break;
166 case _HEAPBADPTR:
167 printf("ERROR - falscher Zeiger im Heap\n");
168 break;
169 case _HEAPBADBEGIN:
170 printf("FEHLER - am Heapanfang!\n" );
171 break;
172 case _HEAPBADNODE:
173 printf( "FEHLER - falscher Knoten im Heap\n" );
174 break;
175 } //switch
176 } //zeigeHeapbelegung
177
178 void zeigeListe(struct Artikel *pArtikel,long nAnzahl) {
179 long nI;
180 printf("Artikelliste:\n");
181 printf("-------------\n");
182 for(nI=0;nI<nAnzahl;nI++) {
183 printf("Artikel-Nr.: %d\n",pArtikel[nI].ArtNr);
184 printf("Name: %s\n",pArtikel[nI].Name);
185 printf("Preis: %.2f\n\n",pArtikel[nI].Preis);
186 getch();
187 } //for
188 } //zeigeListe
189
190 void zeigeMenue(long nAnzahl) {
191 system("cls"); //Aufruf eines CMD-Kommandos
192 printf("Artikelverwaltung: %3d\n",nAnzahl);
193 printf("----------------------\n\n");
194 printf("E = Artikel eingeben\n");
195 //Praeventive Programmierung
196 if (nAnzahl>0) printf("A = Artikelliste anzeigen\n");
197 if (!bExterneDatei) printf("L = Datei "artikel.txt" laden\n");
198 if (nAnzahl>0) printf("S = Speichern in "artikel.txt"\n");
199 printf("B = Beenden\n\n");
200 } //zeigeMenue
201
202 int main(int argc,char *argv[]) {
203 struct Artikel *pArtikel=NULL;
204 long nAnzahl=0;
205 //Zeigt der Zeiger auf nichts, so wird er sicher veraendert und muss
206 // daher als Referenz uebergeben werden:
207 //Kein Fehler, wenn Datei nicht vorhanden.
208 ladeDatei(&pArtikel,&nAnzahl);
209 for(;
{ //Dauerschleife, auch do {} while(true); und andere
210 zeigeMenue(nAnzahl);
211 switch (getch()|0x20) { //in Kleinbuchstaben
212 //switch (tolower(getch())) { //in Kleinbuchstaben
213 //switch (getch()&+~0x20) { //in Grossbuchstaben
214 //switch (toupper(getch())) { //in Grossbuchstaben
215 case 'e':
216 if (eingebeArtikel(&pArtikel,&nAnzahl)) {
217 return 0;
218 } //if
219 break;
220 case 'a':
221 zeigeListe(pArtikel,nAnzahl);
222 break;
223 case 's':
224 speichereDatei(pArtikel,nAnzahl);
225 break;
226 case 'l':
227 if (ladeDatei(&pArtikel,&nAnzahl)) {
228 printf("Fehler beim Laden der Datei "artikel.txt"\n");
229 system("Pause");
230 } //if
231 break;
232 case 'b':
233 printf("\nAusgabe mit "type artikel.txt":\n");
234 system("type artikel.txt");
235 return 0;
236 } //switch
237 } //for
238 system("Pause"); //Aufruf eines CMD-Kommandos
239 return 0;
240 } //main
den bekomme ich aber nicht annähernd zum laufen, aber das wäre eigentlich das was ich bräuchte.
Gruß
Thomas