Probleme beim Sortieren
-
Hallo Leute;
Ich hab ein Problem:
Hab eine binärdatei, die von der struct tMat ist und verschiedene Elemente enthält z.B. Artikelnummer, Lagerbestand u.s.w., die ich einlesen muss, gut und schön klappt alles.Nun will ich die Elemente noch sortieren und hab mir gedacht, nehm ich doch Bubblesort, da wir den schon öfter programmiert haben.
Nun komme ich aber nicht weiter.
Fehler: es kann nicht in Zeigertyp konvertiert werden
Hier erstmal das- Headerfile Mat.h mit der Struct tMat
- Die binär Datei bin.dat
- mein Quellcode bis jetzttypedef struct { char vBez [25+1]; char vNr [12+1]; long Lbst; }tArt;
Christbaumstaender\00\00\00\00\00\00\00\00024 12 00010\00\00M\00\00\00\00\00\00\00Weihnachtsbaumkerze\00\00\00\00\00\00\00024 12 00020\00\00\B1\00\00\00\00\00\00\00Lametta (50g Pckg)\00\00\00\00\00\00\00\00024 12 00030\00\007\00\00\00\00\00\00\00Glaskugeln (Satz)\00\00\00\00\00\00\00\00\00024 12 00040\00\00.\00\00\00\00\00\00\00Lebkuchenherzen Schoko\00\00\00\00006 12 00010\00\00\BE\00\00\00\00\00\00\00Punschglas\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00031 12 00095\00\007\00\00\00\00\00\00Silvesterrakete\00\00\00\00\00\00\00\00\00\00\00031 12 00050\00\00\D6\00\00\00\00\00\00\00Knaller\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00031 12 00099\00\00\00\00\00\00\00\00\00\00Wunderkerze\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00031 12 00078\00\00\00\00\00\00\00\00Engel u.Bergmann (Satz)\00\00\00024 12 00009\00\00\9B\00\00\00\00\00\00\00Fluegelfigurenkarussell\00\00\00024 12 00019\00\00M\00\00\00\00\00\00\00Schwibbogen\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00024 12 00088\00\00B\00\00\00\00\00\00\00Mastgans\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00025 12 00056\00\009\00\00\00\00\00\00\00Adventskalender\00\00\00\00\00\00\00\00\00\00\00001 12 00034\00\00\8F\00\00\00\00\00\00Seiffener Kurrende\00\00\00\00\00\00\00\00024 12 00035\00\00B\00\00\00\00\00\00\00Nusskancker\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00024 12 00123\00\00{\00\00\00\00\00\00\00Raeuchermann\00\00\00\00\00\00\00\00\00\00\00\00\00\00024 12 00246\00\00b\00\00\00\00\00\00Lichterhalter\00\00\00\00\00\00\00\00\00\00\00\00\00024 12 00045\00\00\C8\00\00\00\00\00\00Krippenfiguren\00\00\00\00\00\00\00\00\00\00\00\00024 12 00333\00\00\EA\00\00\00\00\00\00\00Herrnhuter Stern\00\00\00\00\00\00\00\00\00\00024 12 00344\00\00B\00\00\00\00\00\00\00Moritzburger Karpfen\00\00\00\00\00\00031 12 77777\00\00m\00\00\00\00\00\00Sekt Schloss Wackerbart\00\00\00031 12 33333\00\00\EA\00\00\00\00\00\00\00Raeucherkerzen Knox\00\00\00\00\00\00\00024 12 98989\00\00\DE\00\00\00\00\00\00\00Papiersterne\00\00\00\00\00\00\00\00\00\00\00\00\00\00024 12 45554\00\00W\00\00\00\00\00\00Knallbonbon\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00031 12 01995\00\00M\00\00\00\00\00\00Papierschlangen (Pckg)\00\00\00\00031 12 09090\00\00\EA\00\00\00\00\00\00\00
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "mat.h" int main(int argc, char * argv[]) { tArt *pArt; //Pointer auf Struct tArt FILE *pFile; int data, len, i, j, tmp; if(argc != 2) //Parameter ueberpruefen { perror("argc"); exit (EXIT_FAILURE); } pFile = fopen(argv[1],"rb"); //Datei eroeffnen if(pFile == NULL) { perror("fopen"); exit (EXIT_FAILURE); } /*beziehen von Dateigroesse*/ fseek(pFile, 0 ,SEEK_END); //FD nach hinten len = ftell(pFile)/sizeof(tArt); //Laenge eines Elementes von tArt fseek(pFile, 0 , SEEK_SET); //FD auf Anfang /*Speicher ausfassen reservieren*/ pArt = malloc(sizeof(tArt)*len ); //reservierter speicher -> Groesse eines Elements * Laenge if(pArt == NULL) { perror("malloc"); exit (EXIT_FAILURE); } /*Kopiervorgang in buffer*/ data = fread(pArt,sizeof(tArt),len,pFile); //Daten jetzt in pArt if(data != len) //fread gibt anzahl der gelesenden Elemente zurueck { perror("fread"); exit (EXIT_FAILURE); } /*unsorierte Ausgabe*/ for(i=0; i<len; i++) { printf("%-26s %-13s %ld\n",pArt[i].vBez , pArt[i].vNr , pArt[i].Lbst); } /*sortierte Ausgabe*/ for (i=0; i<len; i++) { for(j=i+1; j<len; j++) { if(strcmp(char*)pArt[i],(char*)pArt[j]) > 0) { tmp=(char*)pArt[i]; (char*)pArt[i]=(char*)pArt[j]; (char*)pArt[j]=tmp; } printf("%-26s %-13s %ld\n",pArt[i].vBez , pArt[i].vNr , pArt[i].Lbst); } } free(pArt); exit (EXIT_SUCCESS); }
-
Zeile 57:
Klammern falsch. Was soll das werden? Willst du de beiden Elemente mittels strcmp vergleichen? pArt[i] ist ein konkretes Element vom Typ deines structs, wie soll das in einen Pointer umgewandelt werden? Du meinst wohl (char*)(pArt+i). Aber auch dann wäre das noch nicht richtig. strcmp vergleicht bis zur ersten 0. Enthalten deine Structs auf Byteebene sicher keine Nullen? Und endet es sicher auf 0? Ich denke, auf beide Fragen wird die Antwort Nein sein. Du willst vermutlich ein memcmp machen, bei dem du die Größe angeben kannst. Ich bin mir aber nicht so sicher, ob auch das streng standardkonform ist, da ich mir gerade nicht sicher bin, ob der Wert möglicher Paddingbytes definiert ist. Im Zweifelsfall Nein. Daher: Schreib doch eine Funktion, die zwei Pointer auf deine Structs annimmt und dann zurückgibt, ob die Objekte dahinter größer, kleiner oder gleich sind, indem diese Funktion die konkreten Datenfelder der structs vergleicht. Und wenn du schon so eine Funktion hast, dann kannst du sie auch gleich an die Standardbibliotheksfunktion qsort übergeben und du hast mit einem Schlag eine viel effizientere und fehlerfreie Lösung.P.S.: Und was du dann in Zeile 59 und folgende versuchst, ist noch viel größerer Unfug. Lern noch einmal die Grundlagen. Aber auch dieses Problem löst sich von alleine, würdest du nur qsort benutzen.
P.P.S.: Ich habe nochmal nachgesehen: Der Wert von Paddingbytes ist "indeterminate". Das heißt, du kannst auch kein memcmp benutzen, sofern du dir nicht 100% sicher bist, dass dein struct kein Padding enthält.
-
Da sind ja haufenweise Fehler drin. Also fehlende Klammern solltest du am besten schon ergänzen, bevor du hier postest. Hier fehlt eine:
if(strcmp(char*)pArt[i],(char*)pArt[j]) > 0)
Des Weiteren versuchst du, eine Variable vom Typ tArt (nämlich pArt[i]) nach char* zu konvertieren. Lass das! Wenn du die beiden Elemente vergleichen willst, kannst du zur Not lieber memcmp verwenden. Damit kannst du dir dann das ganze Gecaste sparen.
-
bin leider völliger anfänger im proggen.
wie könnte ich das machen, wenn ich zwei pointer auf meine struct anlege um diese dann zu vergleichen
wenn ich z.b. die ausgabe sortiert nach artikelnumemr haben will.
Vielen Dank
-
#include <stdio.h> #include <stdlib.h> struct foo { int bar; }; int compare_foos(const void* lhs, const void *rhs) { const struct foo *l = lhs, *r = rhs; if (l->bar < r->bar) return -1; if (l->bar > r->bar) return 1; return 0; } int main() { int i; struct foo foos[]={{4},{3},{6},{2},{8},{6}}; qsort(foos, sizeof(foos) / sizeof(*foos), sizeof(*foos), compare_foos); for(i = 0; i < sizeof(foos) / sizeof(*foos); ++i) printf("%d\n", foos[i].bar); }
-
typedef struct { char vBez [25+1]; char vNr [12+1]; long Lbst; }Artikel; Artikel artikel[2] = {{"B1","V1",4711},{"B2","V2",4712}}; if( artikel[0].Lbst < artikel[1].Lbst ) puts("kleiner"); else puts("größergleich"); und für z.B. qsort als Funktion int vergleich(const void *a,const void *b) { const Artikel *x=a,*y=b; return((x->Lbst>y->Lbst)-(x->Lbst<y->Lbst)); }