/******************************************************************************* * 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 #include #include #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); }