Lösungsvorschlag für Aufgabenstellung



  • Hallo,

    mein Programm bekommt Daten die am Ende bestimmten nummern zugeordnet werden sollen und in Datei geschrieben werden.

    z.B. Daten x.y gehören zur Nummer 2 Ausgabe in Datei Nummer "data_Adr_02"

    Hier habe ich vielleicht eine bessere Erklärung.
    Mein Programm liest anhand einer Parameterdatei Daten von bestimmten Busteilnehmern (1-31).
    Diese Daten sollen jeweils nach dem lesen in eine Datei mit der Nummer der Adresse geschrieben z.B. "data_adr_12" (Daten von Adresse 12)

    Da ich die Adressen nicht kenne (werden anhand der Parameter-Datei erst eingelesen) müssen die einzelnen Datenfächer (zugeordnet zur Adresse) dynamisch sein)

    Ebenso ist die Anzahl der Adressen sowie deren Daten dynamisch.

    Auch kann es vorkommen das als erstes und fünftes von der gleichen Adresse gelesen wird. Diese Daten sollen dann nacheinander in der Datei stehen.

    Die Dateien müssen überschrieben werden und können nicht kurzzeitig gelöscht werden (andere Programme lesen aus den Dateien die Daten).

    Mich würde interessieren wie man so etwas einfach lösen kann.
    Ich selbst habe wahrscheindlich nur die komplizierteste Lösung.

    Danke
    worst_case



  • Hi,

    ich habe es jetzt so gelöst das ich ein struct mit einem 1k char Feld habe.
    Ein Adressfeld mit 31 Adressen für dieses struct.
    Und jedesmal wenn ich eine Adresse habe erzeuge ich mit malloc ein struct mit dem 1 k buffer.
    Dies ist nicht ganz so dynamisch, (wenn ich weniger als 1k Daten habe, habe ich zu viel Speicher reserviert) aber es sollte so einfach funktionieren.
    Nun habe ich aber das Problem das derv Compiler einmal

    struct.feld und einmal struct->feld erwartet. Hier habe ich vermutlich zu wenig Ahnung warum das so ist.
    Anbei mal die komplette main (ja ich weiß, es wird später in einzelne Funktionen zerlegt.)

    #define max_adresse_mpi 31
    
    datenkopfkopf fetchkopf = { 0 , 0 , 0 , 0 , 0 , 0 , 0xFF , 0xFF };
    datenkopfkopf sendkopf  = { 0 , 0 , 0 , 0 , 0 , 0 , 0xFF , 0xFF };
    
    typedef struct
    {
     int mpi_adr;
    char typ;
     int db_nr;
     int byte_nr;
     int datenlaenge;    /* in Worten */
     int var_laenge;     /* in Worten */
    } block;
    
    typedef struct
    {
    char data[1024];
    } datenspeicher;
    
    /*#############################################################################################################*/
    int main(int argc, char *argv[])
    {
    FILE *fp;
    int sst,v,z,y,x,blocknr, max_block;
    //int akt_mpi = 0;
    int zwischenspeicher;
    char *lesen;
    char zeile[255];
    datenspeicher *ausgabepuffer[max_adresse_mpi] = {NULL};
    block *blockkennung;
    char dateipfad[255];
    char dateiname[255];
    
    /* Schnittstelle öffnen */
    
         sst = init_SST("/dev/ttyS1");      /* 1. Schnittstelle (DOS Com:2) */
    
          if (sst <= 0 )
             {
             printf("Fehler beim öffnen der Schnittstelle");
             return 0;
             }
    /*--------------------------------------------------------------------------------------------*/
    /* Parameter-Datei einlesen */
    
            while (1)
                  {
                   if ((fp = fopen("/home/peter/projekte/visual_sst/visual_sst/parameter", "r")) == NULL)
                       {
                       /* ERROR */ ;
                       printf ("parameter-Datei konnte zum lesen für die Schnittstelle nicht geöffnet werden");
                       return -1;
                       }
    
                        max_block = 0;      /* zeilenzähler aus der parameterdatei */
                        /* File komplett einlesen */
    
                        while ( fgets(zeile, sizeof(zeile), fp) )
                              {
                              if (zeile[0] == '#' || strlen(zeile) == 0)
                                 {
                                 continue;
                                 }
    
                                  if (blockkennung == NULL || max_block <= 0)
                                     {
                                      blockkennung = malloc(sizeof(block));
    
                                      sscanf (zeile , "%i , %c , %i , %i , %i , %i" , &blockkennung[0].mpi_adr ,
                                                                                      &blockkennung[0].typ,
                                                                                      &blockkennung[0].db_nr,
                                                                                      &blockkennung[0].byte_nr,
                                                                                      &blockkennung[0].datenlaenge,
                                                                                      &blockkennung[0].var_laenge
                                                                                      );
                                      max_block++;
                                     }
                                  else
                                     {
                                      blockkennung = realloc(blockkennung , ((max_block + 1) * sizeof(block)));
                                      sscanf (zeile , "%i , %c , %i , %i , %i , %i" , &blockkennung[max_block].mpi_adr ,
                                                                                      &blockkennung[max_block].typ,
                                                                                      &blockkennung[max_block].db_nr,
                                                                                      &blockkennung[max_block].byte_nr,
                                                                                      &blockkennung[max_block].datenlaenge,
                                                                                      &blockkennung[max_block].var_laenge
                                                                                      );
                                      max_block++;
                                     }
    
                               }
                         fclose (fp);
    
    /*--------------------------------------------------------------------------------------------*/
    /* jeweiligen Block vorbereiten zum lesen */
    
                for ( blocknr = 0 ; blocknr < max_block ; blocknr++)
                    {
                    if (blockkennung[blocknr].typ == 'D')
                       {
                        fetchkopf.db_nummer = blockkennung[blocknr].db_nr;
                        }
                     else
                        {
                         fetchkopf.db_nummer = 0;
                        }
    
    /*--------------------------------------------------------------------------------------------*/
    /* pro Adresse einen Ausgabepuffer anlegen */
    
              if (ausgabepuffer[blockkennung[blocknr].mpi_adr] == NULL)
                 {
                  ausgabepuffer[blockkennung[blocknr].mpi_adr] = malloc (sizeof(datenspeicher));
                 }
    
    /* Telegrammkopf vorbereiten */
    
              fetchkopf.datentyp = blockkennung[blocknr].typ;
              fetchkopf.wort_nummer = blockkennung[blocknr].byte_nr;
              fetchkopf.anzahl =  (blockkennung[blocknr].datenlaenge * blockkennung[blocknr].var_laenge) / 2;
    
              fetchkopf.koordinierungsbyte = 0xFF;
              fetchkopf.koordinierungsbit = 0xFF;
    
                 lesen = malloc(((fetchkopf.anzahl + 1) * 2 ) * sizeof(char));
    
                    if (NULL == lesen)
                       {
                       printf("Hoppla - nicht genug Speicher für Variable lesen\n");
                       exit(-1);
                       }
    
    /* Daten von SPS holen */
    
             y = Fetch_SST(sst , &fetchkopf , lesen);
    
    /* 250ms */
           usleep(250);
    
    /*################ Zwischenspeichern in Buffer ###########################################################*/
    
             for ( z = 0 ; z < (fetchkopf.anzahl + 1) ; )
                 {
                 switch (blockkennung[blocknr].var_laenge)
                      {
                   case 1:            /* Byte */
                           zwischenspeicher = (int)(lesen[z]);
                           z++;
                           break;
    
                   case 2:           /* Worte */
                           zwischenspeicher = (int)((lesen[z] << 8) + lesen[z + 1]);
                           z = z + 2;
                           break;
    
                   case 4:           /* Doppelworte / Real */
                           zwischenspeicher = (int)( (lesen[z] << 24) + (lesen[z + 1] << 16) +
                                                        (lesen[z + 2] << 8) + lesen[z + 3]);
                           z = z + 4;
                           break;
    
                   default:          /* kein korrektes Format */
                           printf ("Als Variablenlänge wurde in der Parameter-Datei ein falscher Wert angegeben\n");
                           printf ("Dieser darf nur 1,2,4 (Bytelänge) enthalten\n");
                           printf ("Bitte komplette Zeile überprüfen (DB-Nr muss wenn nicht benötigt wird 0 betragen\n");
                           break;
                        }
    
    /*################ alle Daten aufsammeln ###########################################################*/
                    sprintf(zeile ,"%i\n" , zwischenspeicher);
                    strcat (ausgabepuffer[blockkennung[blocknr].mpi_adr]->data , zeile);
                    }
    
             free(lesen);
           } 
    
    /*################ AUSGABE in Datei ###########################################################*/
    
                for ( v = 0 ; v < max_adresse_mpi ; v++)
                    {
                    if (strlen(ausgabepuffer[v]->data) > 0);
                       {
                       strcpy(dateipfad , "/srv/www/htdocs/data/");
                       sprintf(dateiname , "data_mpi_%i2",blockkennung[blocknr].mpi_adr);
                       strcat(dateipfad , dateiname);
    
                       if ((fp = fopen(dateipfad , "w+")) == NULL)
                          {
                          printf ("Das datafile %s konnte nicht geöffnet-erzeugt werden\n" , dateipfad);
                          return -1;
                          }
    
                        printf("%s",ausgabepuffer[v]->data);
                        fclose (fp);
                        }
    
                    }
    
    /* Adressen der Ausgabepuffer löschen */
    
                for ( v = 0 ; v < max_adresse_mpi ; v++)
                    {
                    if (ausgabepuffer[v] != NULL);
                       {
                       free(ausgabepuffer[v]);
                       ausgabepuffer[v] = NULL;
                       }
                    }
    
         }
    
      x = close_SST(sst);
    
      return EXIT_SUCCESS;
    }
    

Anmelden zum Antworten