C-Programmierung: Aufgaben: Elektrische Messdaten
Aus Wikibooks
[Bearbeiten] Aufgabenstellung
Schreiben Sie ein Programm, das eine Messdatendatei, die Strom- und Spannungswerte enthält, ausliest und daraus folgende Kennwerte für jede Größe berechnet:
- Minimal- und Maximalwert,
- Gleichanteil (linearer Mittelwert),
- Effektivwert (geometrischer Mittelwert),
- Wirk- und Blindleistung.
Der Name der Datei soll als Kommandozeilenargument übergeben werden. Über die Angabe einer Option in der Kommandozeile sollen nur die Messdaten auf dem Bildschirm ausgegeben werden. Aufrufbeispiele für das Programm sind
- Berechnung und Ausgabe der Kennwerte: Aufgabe07.exe messdaten.txt
- Ausgabe der Messdatenpaare: Aufgabe07.exe messdaten.txt -print
Vor der Berechnung oder Ausgabe sollen alle Messwerte eingelesen werden. Auf die Daten soll über ein Array von Zeigern, die auf jeweils ein Messdatenpaar verweisen angesprochen werden. Nach dem letzten Datenpaar soll das nachfolgende Element ein Null-Pointer sein, um das Ende zu markieren. Die Datenstruktur könnte zum Beispiel wie folgt definiert werden:
typedef struct messwerte { float spannung, strom; }MESSWERTE; MESSWERTE *daten[MAX ANZAHL];
Die Berechnung und Ausgabe der Kennwerte auf dem Bildschirm soll in einer eigens definierten Funktion realisiert werden. Die Ausgabe der Messwerte soll ebenfalls durch eine Funktion erfolgen. Dabei sollen die Werte tabellarisch auf dem Bildschirm seitenweise ausgeben werden (pro Ausgabeseite 25 Zeilen). Folgende Fehlersituationen sind zu berücksichtigen:
- Die Anzahl der Kommandozeilenargumente ist falsch.
- Die Messdatendatei lässt sich nicht öffnen.
- Beim Einlesen der Messdaten steht kein Speicherplatz mehr zur Verfügung.
- In der Messdatendatei stehen mehr Datenpaare als im Array gespeichert werden können.
Im Fehlerfall soll das Programm auf dem Bildschirm eine entsprechende Meldung ausgeben, ggf. bereitgestellten Speicher wieder freigeben und sich beenden.
[Bearbeiten] Musterlösung
# include<stdio.h> # include<string.h> # include<stdlib.h> # include<math.h> # define MAX_ANZAHL 700 # define PI 3.14159265 //Prototyp der Struktur typedef struct messwert { float spannung, strom; } MESSWERTE; //Prototyp der Funktionen int BerechnungAusgabe(MESSWERTE *daten[],int start); int AusgabeMessdaten(MESSWERTE *daten[],int start); void speicherfreigabe(MESSWERTE *daten[],int start); //Hauptfunktion //============================================================================================================ int main(int argc, char *argv[]) { int i=0; int start; MESSWERTE *daten [MAX_ANZAHL]; //Array von Zeigern float sp,str;//spannung,strom FILE *fp; if(argc==1) //keine Parameter eingegeben, Fehler melden und Hilfestellung { printf("Ihre Eingabe stimmt nicht!"); printf("\n geben sie einen Namen fuer das zu oeffnende Argument an \n z.b.name.txt zum oeffnen und verarbeiten!"); printf("\n wenn der Inhalt gezeigt werden soll name.txt -print"); return 1; } fp = fopen(argv[1],"r"); //Öffnen der Datei zum Lesen if(fp == NULL) //wenn datei nicht geöffnet werden konnte fehler hinweise und ende { fprintf(stderr, "\nFehler beim oeffnen der Datei %s\n",argv[1]); printf("Ihre Eingabe ist moeglicherweise falsche bechten sie die beispiele!"); printf("\n geben sie einen namen fuer das zu oeffnende argument an \n z.b.name.txt zum oeffnen und verarbeiten!"); printf("\n wenn sie den inhalt gezeigt werden soll name.txt -print"); return 2; } if (argc==3)//filtern der eingabe ob argument belegt und wenn richtig if(strcmp (argv[2],"-print")!=0) { printf("\n\nder Parameter %s ist falsch",argv[2]); printf("\n wenn sie den inhalt gezeigt werden soll name.txt -print"); return 3; } fprintf(stderr, "\nDatei %s wurde zum Lesen geoeffnet!\n\n",argv[1]); printf("%s;%s",argv[1],argv[2]); start=0; while(fscanf(fp,"%f;%f\n",&str,&sp)!=EOF && start < MAX_ANZAHL-1) //einlesen der messreihe { // Speicherplatz anfordern if((daten[start] = (MESSWERTE*) malloc( sizeof (MESSWERTE))) == NULL) { fprintf(stderr,"Kein Speicher mehr\n"); fclose(fp); speicherfreigabe(daten,start); return -1; } //kopieren der hielfs varieablen auf das array daten[start]->strom=str; daten[start]->spannung=sp; start++; } // anfügen des null pointers daten[start] = NULL; if (start >= MAX_ANZAHL) //wenn mehr messwerte als speicher daressen vorhanden sind fehler printf("beim einlesen der messdaten steht kein speicherplatz mehr im array zu verfuegung"); fclose(fp); switch (argc) //fall unter scheidung zwischen berechen und ausgaber der reihe { case 2: BerechnungAusgabe(daten,start); //aufruf der rechen funktion break; case 3: //filtern der eingabe AusgabeMessdaten(daten,start); break; default: printf("\nihre eingabe wurde nicht akzeptiert, eventuell wurden zu viele Parameter eingegeben"); break; } speicherfreigabe(daten,start); return 0; } // Funktion zum Ermitteln der benötigten Daten aus der Messreihe und Berechnung //============================================================================= int BerechnungAusgabe(MESSWERTE *daten[],int start) { double max_strom,max_spannung,min_strom,min_spannung; double u_gleichricht,i_gleichricht,u_effektiv, i_effektiv,p_wirk,p_blint; double max_spannung_sp1, max_spannung_sp2,max_strom_sp1,max_strom_sp2,cos_phi; float temp1,temp2,temp3,temp4; int i; max_strom=0; max_spannung=0; min_strom=0; min_spannung=100000000; //suchen von min max wertren //=================================================================================================== for(i=0;i<start;i++) { if(max_strom<daten[i]->strom ) { max_strom=daten[i]->strom; } if (max_spannung<daten[i]->spannung) { max_spannung=daten[i]->spannung; } if( min_strom>daten[i]->strom) { min_strom=daten[i]->strom; } if( min_spannung>daten[i]->spannung) { min_spannung=daten[i]->spannung; } } //Emittlung von daten zur bestimunge des cos phi //================================================================================= max_spannung_sp1=0; max_spannung_sp2=0; max_strom_sp2=0; max_strom_sp1=0; temp3=0; temp4=0; temp1=0; temp2=0; for(i=0;i<start-2;i++)//schleife zum finder der maxima von strom und spannung und deren abstaende { if (daten[i]->spannung>daten[i+1]->spannung&&daten[i]->spannung>daten[i+2]->spannung) { if (daten[i]->spannung>daten[i-1]->spannung &&daten[i]->spannung>daten[i-2]->spannung) if(temp2==0 && temp1!=0) { max_spannung_sp2=daten[i]->spannung; temp2=(float)i; } } if (daten[i]->spannung>daten[i+1]->spannung&&daten[i+2]->spannung ) { if (daten[i]->spannung>daten[i-1]->spannung && daten[i-2]->spannung) if(temp1==0) { max_spannung_sp1=daten[i]->spannung; temp1=(float)i; } } if(daten[i]->strom>daten[i+1]->strom&&daten[i]->strom>daten[i+2]->strom) { if (daten[i]->strom>daten[i-1]->strom&&daten[i]->strom>daten[i-2]->strom) if (temp4==0 && temp3!=0) { max_strom_sp2=daten[i]->strom; temp4=(float)i; } } if(daten[i]->strom>daten[i+1]->strom&&daten[i]->strom>daten[i+2]->strom) { if (daten[i]->strom>daten[i-1]->strom&&daten[i]->strom>daten[i-2]->strom) if (temp3==0) { max_strom_sp1=daten[i]->strom; temp3=(float)i; } } } //berechnung der einzelen daten //=============================================================================================== //berechnen des glechrichtwertes u_gleichricht=2/PI*max_spannung; i_gleichricht=2/PI*max_strom; //berechnen der effektivwertes u_effektiv=max_spannung/sqrt(2); i_effektiv=max_strom/sqrt(2); // Berechnung phasenverschiebungswinkel cos_phi=(temp1-temp3)*360/(temp2-temp1); //berechnung der leistungs daten p_wirk=u_effektiv*i_effektiv*cos(cos_phi*PI/180); p_blint=u_effektiv*i_effektiv*sin(cos_phi*PI/180); //Ausgabe der berechneten werte //=============================================================================================== printf("\n\nDie berechneten werte fuer ihr Messdatenreihe lauten:"); printf("\n\n=========================================="); printf("\n \t\t|| Strom || Spannung\t||"); printf("\n=========================================="); //ausgabe minima maxima printf("\n maxima\t\t|| %3.3lf A || %3.3lf V\t||",max_strom,max_spannung); printf("\n=========================================="); printf("\n minima\t\t||%3.3lf A || %3.3lf V\t||",min_strom,min_spannung); printf("\n=========================================="); //ausgabe der effektivwerte printf("\n Effektivwert\t|| %3.3lf A || %3.3lf V\t||",i_effektiv,u_effektiv); printf("\n=========================================="); //ausgabe der gleichrichtwerte printf("\n Gleichrichtwert|| %3.3lf A || %3.3lf V \t||",i_gleichricht,u_gleichricht); printf("\n=========================================="); //ausgabe der leistungs daten printf("\n\n cos_phi:\t%3.3f Grad",cos_phi); printf(" \n Wirkleistung:\t %3.3lf W\n Blindleistung:\t % 3.3lf VAR\n",p_wirk,p_blint); return 0; } // Ausgabe der Messreihe //======================================================== int AusgabeMessdaten (MESSWERTE *daten[],int start) { int i; printf("\n\nEs werden je seite 25 zeilen ausgegben\n zum weiterkommen <enter> druecken. ;-)"); printf("\n\tSpanung || Strom"); for(i=0;i<start;i++) { if(i%25==0) getchar();//alle 25 zeilen enter drücken printf("%4d %8.4f || %8.4f\n", i,daten[i]->spannung,daten[i]->strom); } return 0; } // funktion zum freigeben des speicherplatzes //========================================================================================= void speicherfreigabe(MESSWERTE *daten[],int start) { int start1; //schleife zum freigeben jeder einzelnden array adress for(start1=0;start1<start;start1++) { free(daten[start1]); } }