All pastes #65086 Raw Edit

HF

public text v1 · immutable
#65086 ·published 2006-06-13 11:49 UTC
rendered paste body
/*******************************************************************************
* datenfilter.c                                                                *
* Dieses Programm liest Datensätze zweier Maschinen M1 und M2 aus einer Datei  *
* und generiert daraus ein geräteunabhängiges, drittes Format, welches sich    *
* zum direkten Ansehen am Bildschirm eignet. Nicht syntax-konforme Zeilen      *
* werden in eine Fehlderdatei geschrieben                                      *
* @version $Id: datenfilter.c,v 1.1 2005/12/19 22:20:32 mk Exp $               *
* @author Maximilian Kellner                                                   *
*******************************************************************************/

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define CONFIRMEXIT "\nPress any key to exit ..."
#define MAXFILENAME 255
#define MAXDIGITS 128
#define KELVIN_CELSIUS -273;
#define ERRORFILE "errors.txt"
#define MDFILE "merrs.txt"

/* Datenstruktur fuer das dritte unabhängige Format
 * NAME: Zusätzlicher Wert zur Unterscheidung der Maschinen; 0 = ungültig
 * TIME: Minuten
 * RPM: 1/min 
 * SPEED: km/h
 * FUEL: l/100km 
 * TEMP: Celsius-Grad
 */

struct mData {
          int name;
          int time;
          int rpm;
          int speed;
          float fuel;
          int temp;
};

/* Prototypes */
void displayTable (struct mData *md);
struct mData getLine (char mdLine[]);


int main (void) {
    
    FILE *mdFile, *errFile;
    int i=0;

    char mdLine[250];
    char mdFilename[MAXFILENAME];

    struct mData md;


    /* Datei fuer das Fehlerprotokoll zuerst in jedem Fall oeffnen
     * Bereits vorhandene Daten werden ueberschrieben!
    */
    errFile = fopen (ERRORFILE, "w");
    if (errFile == NULL) {
        fprintf(stderr, "Fehler beim Oeffnen der Datei %s \n", ERRORFILE);
    }

    printf("Bitte Pfad der zu oeffnenden Datei angeben: \n");
    
    /* Dateiname eingeben */
    fflush(stdin);
    scanf("%s", mdFilename);


    mdFile = fopen (mdFilename, "r");
    if (mdFile == NULL) {
        fprintf(stderr, "Fehler beim Oeffnen der Datei %s\n", mdFilename);
    } else {
    
           /* Loop durch die Zeilen der Datei bis zum Ende */
           while (!feof(mdFile)) {
                 
                 if (i%20 == 0) {
                     printf("Zeit   Umdrehungen   Geschwindigkeit   Verbrauch  Temperatur\n");
                     printf("[m:s]\t     [1/s]\t      [km/h]   [l/100km]    [Grad C]\n");
                      }
                 i++;
           
                 fgets (mdLine, sizeof(mdLine), mdFile);
                 /* Scruct mit den richtig konvertierten Datensaetzen */
                 md = getLine(mdLine);
                 
                 /* Kann sein, dass die Zeile fehlerhaft war, also 
                  * kommt ein entsprechendes Scruct zurueck
                  */
                 if (md.name == 0) {
                    fprintf(errFile, "%s", mdLine);
                 }
          
                 /* Tabellarische Ausgabe der Datensaetze */
                 displayTable(&md);
           }
           
           // Datei mit den Datensaetzen schliessen
           fclose(mdFile);
    }


    if (errFile != NULL) fclose(errFile);

    /* Für die Windowsuser: Cmd Box bleibt offen */
    printf(CONFIRMEXIT);
    fflush(stdin);getchar();

    return 0;
    
}


struct mData getLine (char mdLine[]) {

     char  cTmp[10]; /* Hilfsvariable zur Zwischernspeicherung von Nachkommastellen */
     char  sTmp[MAXDIGITS+1]; /* Hilsvariable zur Zwischenspeicherung von strings */
     char  sTmp1[MAXDIGITS+1]; /* Hilsvariable zur Zwischenspeicherung von strings */
     int   iTmp[5]; /* Hilfsvariable zur Zwischenspeicherung von ints */
     float fTmp[5]; /* Hilfsvariable zur Zwischenspeicherung von floats */

     struct mData md;
     int x=0;

     /* Format von M1
      * Testen ob die Zeile zu M1 passt
      * %d.%c%c = I-NUMBER.DIGIT DIGIT
      * %d = I-NUMBER
      */
     if (sscanf(mdLine, "%d.%c%c,%d,%d,%d.%c%c,%s", 
                        &iTmp[0],&cTmp[1],&cTmp[2],
                        &md.rpm,
                        &md.speed,
                        &iTmp[1],&cTmp[3],&cTmp[4],
                        sTmp) == 9) {
                        
                        /* Speichern um welche Maschine es sich handelt */
                        md.name = 1;

                        /* Umständlicher Sonderfall: Das letze %s kann nicht etwa
                         * ein %d sein, weil sonst auch Eingaben wie 90.0xyz
                         * möglich wären - deshalb als string extrahieren und
                         * gesondert behandeln
                         */
                        if ( sscanf (sTmp, "%d%c", &md.temp) > 1) md.name = 0;
 
                        /* Time als String zusammensetzen und anschließend
                         * in float umwandeln 
                         */
                        sprintf(sTmp, "%d.%c%c", iTmp[0],cTmp[1],cTmp[2]);
                        sscanf(sTmp, "%f", &fTmp[0]);

                        /* Fuel als String zusammensetzen und anschließend
                         * in float umwandeln
                         */
                        sprintf(sTmp, "%d.%c%c", iTmp[1],cTmp[3],cTmp[4]);
                        sscanf(sTmp, "%f", &md.fuel);

                        /* Prüfen ob einer der Werte negativ ist oder 
                         * ob Name gleich 0 ist
                         */ 
                        if (md.name == 0 || md.time < 0 || md.rpm < 0 ||
                            md.speed < 0 || md.fuel < 0 || md.temp < 0 ) md.name = 0;
                        else {
          /* Alle Werte der Zeile sind ok
           * Konvertierung von Einheiten */
          /* Zeit von Minuten in Sekunden umrechnen */

           md.time = fTmp[0] * 60;
          
           md.rpm = md.rpm/60;
          
          }


     /* Format von M2
      * %d.%c%c = I-NUMBER.DIGIT DIGIT
      * %d = DIGIT
      * Tricky: M2 Name kann unendlich lang sein
      * Muss man mit folgendem Konstrukt filtern: [0-9A-Z]
      * %s geht nicht, weil das der komplette Reststring wäre
      */
     } else if (sscanf(mdLine, "%d$%[0-9A-Z]$%d$%d$%d$%s", 
                        &md.time,
                        &sTmp1,
                        &md.temp,
                        &md.speed,
                        &iTmp[3],
                        sTmp) == 6) {

                        /* Speichern um welche Maschine es sich handelt */
                        md.name = 2;

        if ( sscanf (sTmp, "%d%c", &md.rpm) > 1) md.name = 0;
        
        /* Name darf nur mit einem Grossbuchstaben anfangen, 
         * und muss mindestens 2 Zeichen lang sein
         */
        if((!isupper(sTmp1[0])) || (strlen(sTmp1) < 2))
        md.name = 0;

        sprintf(sTmp, "%d", iTmp[3]);
        sscanf(sTmp, "%f", &md.fuel);
        
        if (md.name == 0 || md.time < 0 || md.rpm < 0 || md.speed < 0 ||
        md.fuel < 0 || md.temp < 0 )   md.name = 0;
        else {

      /* Alle Werte der Zeile sind ok
       * Konvertierung von Einheiten

        /* Geschwindigkeit in km */
        md.speed = md.speed*3.6;
        /* Verbrauch in l/100km */
        md.fuel = ((md.fuel/1000*60)/md.speed)*100;
        /* RPM in R/s */
        md.rpm = md.rpm/60;
        /* Gard in Celsius */
        md.temp = md.temp + KELVIN_CELSIUS;
        
        }
     
     /* Unbekanntes Format
      * Scruct wird mit 0-Werten gefuellt
      * Als Name der Maschine wird 0 eingetragen
      */
     } else {

        md.name = 0;
     }

return md;      
                        
}



void displayTable (struct mData *md) {

    /* Name der Maschine is 0 --> Unbekanntes Format
     * Anstatt von Werten sollen * ausgegeben werden
     */
    if (md->name == 0)
       printf("%5s%13s %17s %11s %11s\n", "*", "*", "*", "*", "*");
    /* Tabellarische Ausgabe eines korrekten Datensatzes */
    else 
         printf("%02d:%02d%13d %17d %11.2f %11d\n",
         md->time/60, md->time%60, md->rpm, md->speed, md->fuel, md->temp);
}