Daten aus einer Binärdatei auslesen + nach best. Gesichtspunkten sortieren



  • Hallihallo,

    ich habe ein Problem:
    Ich muss für's Studium ein Programm schreiben, welches eine Binärdatei ausliest und die ausgelesenen Daten dann nach bestimmten Gesichtspunkten sortiert.

    Jetzt habe ich wie gesagt diese Binärdatei in meinem C-Programm geöffnet, funktioniert auch einwandfrei, und möchte nun meine Daten sortiert ausgeben.

    Ich werfe jetzt erstmal die benötigte Struktur hier in den Raum:

    struct Satz{
      char Filiale[21];
      float Umsatz;
      float Bestand;
      float Beschaeftigte;
      float Loehne;
      unsigned short Quadratmeter;
      float Anlagevermoegen;
    }__attribute__ ((packed));
    

    Ich möchte nun meine Datensätze nach dem Umsatz sortiert ausgeben.
    Habe es schon versucht mit einem eigenen Sortieralgorithmus (einfach ne Vorschleife und geprüft, ob die derzeitige Zahl größer oder kleiner ist als die vorhergehende...), das hat aber nicht geklappt, weil so zwar die Umsätze richtig ausgegeben werden, jedoch nicht die dazugehörigen Filialen z.B..

    Kurz gesagt: Ich möchte, dass die Datensätze sortiert nach der Größe des Umsatzes ausgegeben werden und zwar da wo der größte Umsatz ist als erste und der kleinste Umsatz als kleinstes.

    Wie stelle ich das an?

    Die Datei Handel.dat bekommt ihr hier: http://www.voodoo4u.net/Handel.dat
    Abschließend noch mein derzeitiger Code:

    #include <stdio.h>
    //#include <stdlib.h>
    #include <conio.h>
    #define N 10
    
    float Arbeitseffektivitaet;
    float Mitarbeiterlohn;
    
    struct Satz{
      char Filiale[21];
      float Umsatz;
      float Bestand;
      float Beschaeftigte;
      float Loehne;
      unsigned short Quadratmeter;
      float Anlagevermoegen;
    }__attribute__ ((packed));
    
    int Ausgabe1()
    { 
      struct Satz myRECORD; // C style structure declaration
      FILE *fh;
      int num_read;
    
      fh = fopen("Handel.dat","rb");
      while (!feof(fh))
      {
        num_read=fread(&myRECORD,sizeof(myRECORD),1,fh);
        Arbeitseffektivitaet = (myRECORD.Umsatz/myRECORD.Beschaeftigte);
        Mitarbeiterlohn = (myRECORD.Loehne/myRECORD.Beschaeftigte);
        printf("Filiale:               %s\n",myRECORD.Filiale);
        printf("Umsatz:                %f\n",myRECORD.Umsatz);
        printf("Bestand:               %f\n",myRECORD.Bestand);
        printf("Beschaeftigte:         %f\n",myRECORD.Beschaeftigte);
        printf("Loehne:                %f\n",myRECORD.Loehne);
        //printf("Groesse:               %i\n",myRECORD.Quadratmeter);
        //printf("Anlagevermoegen:       %f\n",myRECORD.Anlagevermoegen);
        printf("Mitarbeiterlohn:       %f\n",Mitarbeiterlohn);
        printf("Arbeiteseffektivitaet: %f\n\n",Arbeitseffektivitaet);
        getch();
      }
      fclose(fh);
      getch(); 
    }
    
    MenueSortedBy()
    {
      char menuewahl;
      printf("Bitte treffen Sie Ihre Wahl:\n"
             "1) Filialen nach Umsatz sortieren\n"
             "2) bla\n"
             "3) bla2\n"
             "Ihre Auswahl: ");
    
      do 
        {
        menuewahl = getche();
        printf("\b"); 
        }
      while ((menuewahl != '1') && (menuewahl != '2') && (menuewahl != '3'));
    
      if (menuewahl == '1')
      {
      printf("\n\n");
      Ausgabe1();
      }
    
    }
    
    int main()
    {
      MenueSortedBy();
    
      getch();
      return 0;
    }
    


  • Du solltest erstmal alle Datensätze in der Datei in ein Array vom Typ struct Satz einlesen. Das kannst du dann sortieren.

    Edit: Außerdem solltest du [cpp]-Tags statt der [code]-Tags verwenden und deinen Code sauber einrücken.



  • Habe es mal überarbeitet, cpp Tags verwendet + Code eingerückt, hoffe so ists iO.

    Kannste mir sagen, wie ich das in nen Array gepackt bekomme?
    Sorry, bin was C angeht echt...naja...;)



  • Eigentlich sind die Änderungen am Code minimal. Statt einfach nur eine Struktur anzulegen, legst du ein Array an:

    struct Satz myRECORD[N]; // Ich nehme an N steht für die Zahl der Sätze in der Datei
    

    Und beim Aufruf von fread() musst du eigentlich nur den 3. Parameter anpassen.



  • Seh ich das richtig, dass ich also

    struct Satz{ 
      char Filiale[21]; 
      float Umsatz; 
      float Bestand; 
      float Beschaeftigte; 
      float Loehne; 
      unsigned short Quadratmeter; 
      float Anlagevermoegen; 
    }__attribute__ ((packed));
    

    einfach nur in

    struct Satz myRECORD[N]{ 
      char Filiale[21]; 
      float Umsatz; 
      float Bestand; 
      float Beschaeftigte; 
      float Loehne; 
      unsigned short Quadratmeter; 
      float Anlagevermoegen; 
    }__attribute__ ((packed));
    

    ändern muss?
    Wenn ich das habe - wie sortiere ich das ganze dann?



  • voodoopuppe schrieb:

    Wenn ich das habe - wie sortiere ich das ganze dann?

    mit 'qsort'.
    so ungefähr

    qsort (myRECORD, N, sizeof(struct Satz), sortfunction);
    

    die sortfunktion sieht etwa so aus, wenn du nach umsatz sortieren willst

    // nach oben kommt das kleinste
    int sortfunction (void *a, void *b)
    {
       struct Satz *r1 = (struct Satz*)a;
       struct Satz *r2 = (struct Satz*)b;
    
       // kleiner
       if (r1->Umsatz < r2->Umsatz)
          return -1;
       // grösser
       if (r1->Umsatz > r2->Umsatz)
          return 1;
       // beide gleich
       return 0;
    }
    

    qsort gräbt dir das ganze array um 😉
    sollte dieses komplette umschaufeln ein (geschwindigkeits)problem werden, dann könnte man alternativ ein 'N'-elemente grosses array mit pointern auf die Sätze sortieren...



  • struct Satz myRECORD[N]{ 
      char Filiale[21]; 
      float Umsatz; 
      float Bestand; 
      float Beschaeftigte; 
      float Loehne; 
      unsigned short Quadratmeter; 
      float Anlagevermoegen; 
    }__attribute__ ((packed));
    

    bringt mir folgendes:

    main.c:9: error: syntax error before '{' token
    main.c:17: error: syntax error before '}' token
    main.c:17: warning: empty declaration
    main.c: In function sortfunction': main.c:26: error: dereferencing pointer to incomplete type main.c:26: error: dereferencing pointer to incomplete type main.c:29: error: dereferencing pointer to incomplete type main.c:29: error: dereferencing pointer to incomplete type main.c: In functionAusgabe1':
    main.c:37: error: storage size of 'myRECORD' isn't known
    main.c:45: error: `Arbeitseffektivitaet' undeclared (first use in this function)
    main.c:45: error: (Each undeclared identifier is reported only once
    main.c:45: error: for each function it appears in.)

    main.c:46: error: `Mitarbeiterlohn' undeclared (first use in this function)

    main.c: In function main': main.c:106: error:myRECORD' undeclared (first use in this function)
    main.c:106: error: invalid application of `sizeof' to incomplete type `Satz'

    Was ist denn daran nun wieder falsch?

    #include <stdio.h>
    //#include <stdlib.h>
    #include <conio.h>
    #define N 10
    
    float Arbeitseffektivitaet;
    float Mitarbeiterlohn;
    
    struct Satz myRECORD[N]{ 
      char Filiale[21]; 
      float Umsatz; 
      float Bestand; 
      float Beschaeftigte; 
      float Loehne; 
      unsigned short Quadratmeter; 
      float Anlagevermoegen; 
    }__attribute__ ((packed));
    
    // nach oben kommt das kleinste 
    int sortfunction (void *a, void *b) 
    { 
       struct Satz *r1 = (struct Satz*)a; 
       struct Satz *r2 = (struct Satz*)b; 
    
       // kleiner 
       if (r1->Umsatz < r2->Umsatz) 
          return -1; 
       // grösser 
       if (r1->Umsatz > r2->Umsatz) 
          return 1; 
       // beide gleich 
       return 0; 
    } 
    
    int main()
    {
    qsort (myRECORD, N, sizeof(struct Satz), sortfunction);
    
    getch();
    return 0;
    }
    

    Kann mir da keiner helfen? 😞
    Ich rall's irgendwie nich *heul*



  • was soll das machen "}__attribute__ ((packed)); " ??

    Versuche es mal damit:

    struct Satz { 
      char Filiale[21]; 
      float Umsatz; 
      float Bestand; 
      float Beschaeftigte; 
      float Loehne; 
      unsigned short Quadratmeter; 
      float Anlagevermoegen; 
    } myRECORD[N];
    


  • das wollt er machen--> http://www.pronix.de/pronix-775.html
    ist aber nicht ansi c 😉



  • So, habe das jetzt als Array gemacht. Wie geb ich das jetzt aus? :|



  • In einer Schleife:

    for(i=0;i<N;++i)
    {
      printf("%s\n",myRecord[i].Filiale);
      ...
    }
    


  • Wusste ich's doch...! Danke trotzdem!
    Und wie sortiere ich das ganze jetzt?



  • Wieso stellst du eine bereits beantwortete Frage überhaupt nochmal? Zum Sortieren kannst du qsort() verwenden.

    (wenn du viel Langeweile hast, kannst du dich auch nach verschiedenen Sortieralgorithmen umsehen und diese implementieren)





  • Ich hatte das ganze ja schonmal hinbekommen - das Problem dabei war, dass ich die Datensätze irgendwie nicht korrekt mit übernommen habe.
    Und das Problem möchte ich eben gern meiden.

    Deswegen nochmal die Frage

    //EDIT:
    Oh ich glaub es funktioniert 😉
    Muss ich es nur noch umbasteln, dass das größte dann oben steht 🙂



  • voodoopuppe schrieb:

    Muss ich es nur noch umbasteln, dass das größte dann oben steht 🙂

    Und das dürfte auch nicht so schwer werden 😉 Du mußt in deiner Vergleichsfunktion nur die Rückgabewerte -1 und 1 vertauschen, dann hast du die umgekehrte Sortierung.



  • hab einfach > und < vertauscht, hat den selben Effekt 😉
    Andere Frage:
    Wie gebe ich die sortierten Daten aus dem Array jetzt noch über den Drucker aus?

    Kann ich das einfach so machen:
    [CPP]FILE* printer = fopen("LPT1","w");
    if(!printer)
    {
    printf("Drucker konnte nicht gefunden werden, bzw. ist nicht eingeschaltet.\n");
    return EXIT_FAILURE;
    }

    fputs(??Kommt hier einfach der Name der Funktion rein wo ich die Daten sortiert ausgebe??,printer);
    fputc('\f',printer);

    fclose(printer);

    return EXIT_SUCCESS;[/CPP]



  • voodoopuppe schrieb:

    hab einfach > und < vertauscht, hat den selben Effekt 😉

    klar, weil die umsätze alle 0 sind 😉



  • Du könntest deiner Ausgabefunktion einen zusätzlichen Parameter "FILE* fout" mitgeben und dort drin über fprintf() ausgeben (funktioniert genauso wie printf(), erhält aber als ersten Parameter die Zieldatei). Dann kannst du im Hauptprogramm entscheiden, wohin die Ausgabe gehen soll - print_data(...,stdout); gibt auf dem Monitor aus, print_data(...,printer); auf dem Drucker.



  • Versteh ich das also richtig, dass du meinst ich soll eine If-Abfrage einbauen, und die soll überprüfen ob fout printer oder stdout ist und wenn printer, dann soll einfach fprintf anstatt von printf genommen werden?

    Also quasi so:

    int Ausgabe(int OrdnenNach,FILE* fout)
    {
     if (fout == printer)
     {
      for(i=0;i<N;++i) 
      { 
        Arbeitseffektivitaet = (myRECORD[i].Umsatz/myRECORD[i].Beschaeftigte);
        Mitarbeiterlohn = (myRECORD[i].Loehne/myRECORD[i].Beschaeftigte);
        fprintf("Filiale:               %s\n",myRECORD[i].Filiale
        fprintf("Umsatz:                %f\n",myRECORD[i].Umsatz);
        fprintf("Bestand:               %f\n",myRECORD[i].Bestand);
        fprintf("Beschaeftigte:         %f\n",myRECORD[i].Beschaeftigte);
        fprintf("Loehne:                %f\n",myRECORD[i].Loehne);
        fprintf("Mitarbeiterlohn:       %f\n",Mitarbeiterlohn);
        fprintf("Arbeiteseffektivitaet: %f\n\n",Arbeitseffektivitaet);
        getch();
      }
      else
    { Ausgabeammonitor....}
      fclose(fh);
    }
    

    (stark gekürzte Variante)


Log in to reply