Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS 1 // nur für Microsoft VS weil der sonst rum nervt
- #include <stdio.h>
- #include <locale.h>
- #include <stdbool.h>
- #include <string.h>
- // Defines
- #define MAXPUNKTE 256
- #define PATH_MAX 4096 /* maximale Länge von einem Linux-Path für eine Datei, inklusive dem NULL am Ende */
- // Structs: unsere Keks-Stanzform
- struct Punkte
- {
- double x[MAXPUNKTE];
- double y[MAXPUNKTE];
- int arrayLaenge;
- };
- // Prototypen
- void MenuAusgabe();
- void Menu(struct Punkte *p); // wir zeigen jeder Funktion wo unser Keks liegt. Bitte behandele unseren Keks gut. Der wird auch von anderen Funktionen später noch bearbeitet. Wir haben nur einen und wollen nicht dass er kaputt geht.
- void DatenAufnehmen(struct Punkte *p);
- void DatenAusgeben(struct Punkte *p);
- void DatenKorrigieren(struct Punkte *p);
- void DatenSpeichern(struct Punkte *p);
- void DatenLaden(struct Punkte *p);
- void DatenBerechnen(struct Punkte *p);
- void DatenGenerieren(struct Punkte *p);
- void LeseStringWert(char *ziel, int maxLaenge); // Hilfsfunktion weil scanf echt nervt bei Texteingabe
- int main(void)
- {
- setlocale(LC_ALL, "de_DE"); // Sprache auf Deutsch stellen/ damit kommer und Punkte angepasst werden
- struct Punkte meinePunkte; // unser einziger wahrer Keks den wir gestanzt haben
- Menu(&meinePunkte);
- return 0; // Rückgabewert 0 an das Aufrufende Programm zurück geben: d.h. wir haben keinen gelben Schnee gegessen
- }//main ende
- //MenuAusgabe ist eine Funktion die Ausgabe des Standards Menus aus gibt
- void MenuAusgabe()
- {
- printf("\n");
- printf("Berechnung eines Flächeninhalts\n");
- printf("===============================\n");
- printf("(1) Daten aufnehmen\n");
- printf("(2) Daten ausgeben\n");
- printf("(3) Daten korrigieren\n");
- printf("(4) Daten speichern\n");
- printf("(5) Daten laden\n");
- printf("(6) Flächeninhalt ermitteln\n");
- printf("(7) Testdaten generieren\n"); // todo: kann in der Endversion weg
- printf("(0) Ende [ESC]\n");
- printf("Treffen Sie eine Wahl und bestätigen Sie mit Enter:\n");
- }
- void Menu(struct Punkte *p) // bei *p ist unser Keks. Wir werden ihn an alle Funktionen weiter geben die den Keks bearbeiten sollen.
- {
- int eingabe;
- MenuAusgabe(); // Die Menu-Ansicht wird ausgegeben
- do
- {
- scanf("%d", &eingabe); // todo: das ist super unsicher hier, bitte keine Buchstaben oder so eingeben
- if (eingabe == 1)
- {
- DatenAufnehmen(p); //ausführen
- MenuAusgabe(); // Die Menu-Ansicht wird ausgegeben
- }
- else if (eingabe == 2)
- {
- DatenAusgeben(p); //ausführen
- MenuAusgabe(); // Die Menu-Ansicht wird ausgegeben
- }
- else if (eingabe == 3)
- {
- DatenKorrigieren(p); //ausführen
- MenuAusgabe(); // Die Menu-Ansicht wird ausgegeben
- }
- else if (eingabe == 4)
- {
- DatenSpeichern(p); //ausführen
- MenuAusgabe(); // Die Menu-Ansicht wird ausgegeben
- }
- else if (eingabe == 5)
- {
- DatenLaden(p); //ausführen
- MenuAusgabe(); // Die Menu-Ansicht wird ausgegeben
- }
- else if (eingabe == 6)
- {
- DatenBerechnen(p); //ausführen
- MenuAusgabe(); // Die Menu-Ansicht wird ausgegeben
- }
- else if (eingabe == 7)
- {
- DatenGenerieren(p); //ausführen
- MenuAusgabe(); // Die Menu-Ansicht wird ausgegeben
- }
- } while (eingabe != 0); //Programm beenden
- /*Die Funktion Menu() beruht auf dem Prenzip eines endlichen Automatens.
- es Läuft eine Schleife durch und wenn ein Menupunkt ausgewählt wird,
- wenden die Funktion in dem Menupunkt ausgeführt. danach geht die Schleife weiter
- und man Befindet sich wieder im Hauptmenu.
- Da die Ausgabe immer wieder kommt ist sie in der Funktion MenuAusgabe() zusammen
- gefasst
- */
- }// Menu beendet
- void DatenAufnehmen(struct Punkte *p)
- {
- bool schleife = true; // Breaker für die schleife
- int zaehler = 0;
- double inputX;
- double inputY;
- double tmpX[MAXPUNKTE]; //temporaere XY-Werte
- double tmpY[MAXPUNKTE];
- printf("Um abzuschließen bitte den ersten Punkt erneut angeben.");
- while (schleife) {
- printf("Geben sie bitte Punkt %d X an:", zaehler + 1);
- scanf("%lf", &inputX); while (getchar() != '\n') {} //ggf auf zahlen gegeprüfen und dann mit getchar arbeiten; ARBEIT!!!!
- tmpX[zaehler] = inputX; //Inhalt von X an denn Array übergeben
- printf("Y an:");
- scanf("%lf", &inputY); while (getchar() != '\n') {} //ggf auf zahlen gegeprüfen und dann mit getchar arbeiten; ARBEIT!!!!
- tmpY[zaehler] = inputY; //Inhalt von Y an denn Array übergeben
- if ((tmpX[0] == inputX && tmpY[0] == inputY && zaehler > 0)) //Fehlerabfangen
- {
- if (zaehler < 4) //Fehlerabfangen eine flaeche hat min 3 Punkte
- {
- printf("Zu weing werte bitte Versuchen sie es erneut.\n");
- }
- schleife = false;
- }
- if (zaehler == MAXPUNKTE - 1) //Zahlen begrenzen um Fehler zu vermeiden
- {
- schleife = false;
- printf("Leider haben sie zuviele Zahlen eingegben\n");
- }
- zaehler++;
- printf("Punkt %d: X:%2f Y:%2f\n", zaehler, inputX, inputY); //Ausgabe welche Zahlen eingebenben wurden
- }
- int zaehler2 = 0;
- while (zaehler2 < zaehler) {
- p->x[zaehler2] = tmpX[zaehler2]; //in X[] und Y[] soll der inhalt von tmpX[] und tmpY[] und dabei soll Punkt: weggekürzt werden
- p->y[zaehler2] = tmpY[zaehler2];
- zaehler2++;
- }
- tmpX[zaehler] = '\n';
- tmpY[zaehler] = '\n';
- p->arrayLaenge = zaehler; //Anzahl der Eingaben Global weiter geben.
- }
- void DatenAusgeben(struct Punkte *p)
- {
- if (p->arrayLaenge > 0)
- {
- int zaehler = 0;
- printf("(2) Daten ausgeben:\n"); //benutzerinfo
- printf("--------------\n");
- while (zaehler < p->arrayLaenge) //Solange in arraylaenge inhalt ist wird dieser ausgebenen
- {
- printf("%d. Punkt: x:%lf\n", zaehler + 1, p->x[zaehler]); //Ausgabe "NR." Punkt: x: "Eingabe x"
- printf(" y:%lf\n", p->y[zaehler]); //Ausgabe y:"Eingabe y"
- zaehler++;
- }
- printf("--------------\n");
- printf("Bitte Enter zum Fortfarhen:\n");
- while (getchar() != '\n') {} //wenn Enter gedrückt wird faehrt das Programm fort
- }
- else {
- printf("Leider sind noch keine Daten vorhanden:\n\n\n\n"); //sollten keine Daten vorhanden sein
- }
- }//ende DatenAusgeben
- void DatenKorrigieren(struct Punkte *p)
- {
- if (p->arrayLaenge > 0) {
- printf("Bitte geben sie den Punkt an den sie bearbeiten wollen.\n");
- printf("Zahlen zwischen 1 und %d sind Zulässig\n", p->arrayLaenge - 1); //Benutzerinfo
- int inputBearbeiten;
- scanf("%d", &inputBearbeiten); //abfrage welcher Datensatz veraendert werden soll
- if (inputBearbeiten <= p->arrayLaenge - 1) { //Vergleich ob der datensatz vorhanden ist
- double xNeu; //Zwischenspeicher für X
- double yNeu; //Zwischenspeicher für Y
- printf("Alt X war %f.\nBitte geben sie X neu an:\n", p->x[inputBearbeiten - 1]);
- scanf("%lf", &xNeu);
- printf("Alt Y war %f.\nBitte geben sie Y neu an:\n", p->y[inputBearbeiten - 1]);
- scanf("%lf", &yNeu);
- printf("xNeu = %f", xNeu);
- p->x[inputBearbeiten - 1] = xNeu; //denn alten X-Wert mit dem neuen überschreiben
- p->y[inputBearbeiten - 1] = yNeu; //denn alten Y-Wert mit dem neuen überschreiben
- if (inputBearbeiten == 1)
- {
- p->x[p->arrayLaenge - 1] = xNeu; //wenn der Erste Wert veraendert werden soll muss der letzte auch geaender werden
- p->y[p->arrayLaenge - 1] = yNeu;
- }
- printf("--------------\n");
- }
- else {
- printf("Die eingabe war zu Groß.\n"); //Eingabe ist begrenzt
- }
- }
- else {
- printf("Leider sind noch keine Daten vorhanden:\n\n\n\n"); //DatenVorhanden ist noch false
- }
- }//ende DatenKorrigieren
- // Info: eine sehr hilfreiche Funktion. persönliche Meinung. Ich hasse scanf()!
- void LeseStringWert(char *ziel, int maxLaenge) {
- while (getchar() != '\n'); // LeseBuffer löschen. keine Ahnung ob das hier nötig ist. Sicher ist sicher.
- fgets(ziel, maxLaenge, stdin);
- // Entferne das newline-Zeichen am Ende des Strings
- size_t laenge = strlen(ziel);
- if (laenge > 0 && ziel[laenge - 1] == '\n') {
- ziel[laenge - 1] = '\0';
- }
- }
- void DatenSpeichern(struct Punkte *p)
- {
- printf("\n");
- printf("(4) Daten speichern:\n");
- printf("--------------------\n");
- printf("Pfadname (Default: koord.txt):");
- char dateipfad[PATH_MAX];
- LeseStringWert(dateipfad, PATH_MAX);
- if (dateipfad[0] == '\0') {
- strcpy(dateipfad, "koord.txt");
- }
- FILE *datei = fopen(dateipfad, "w");
- if (datei == NULL) {
- printf("FEHLER: Die Datei %s konnte nicht zum Schreiben geöffnet werden.\n", dateipfad);
- return;
- }
- for (int i = 0; i < p->arrayLaenge; i++) {
- fprintf(datei, "%.2lf %.2lf\n", p->x[i], p->y[i]);
- }
- fclose(datei);
- printf("Es wurden %d Wertepaare in %s gespeichert.\n", p->arrayLaenge, dateipfad);
- }
- void DatenLaden(struct Punkte *p)
- {
- printf("\n");
- printf("(5) Daten laden:\n");
- printf("--------------------\n");
- printf("Pfadname (Default: koord.txt):");
- char dateipfad[PATH_MAX];
- LeseStringWert(dateipfad, PATH_MAX);
- if (dateipfad[0] == '\0') {
- strcpy(dateipfad, "koord.txt");
- }
- FILE *datei = fopen(dateipfad, "r");
- if (datei == NULL) {
- printf("FEHLER: Die Datei %s konnte nicht zum Lesen geöffnet werden.\n", dateipfad);
- return;
- }
- int c = 0;
- while (fscanf(datei, "%lf %lf", &(p->x[c]), &(p->y[c]) ) == 2) { // todo: kann man das besser machen ohne klammern? ist das überhaupt richtig??? naja scheint so, sieht trotzdem komisch aus
- c++;
- if (c >= MAXPUNKTE) {
- printf("WARNUNG: Das Array ist voll. Die Daten werden nur bis zum Maximum von %d gelesen.\n", MAXPUNKTE); // todo: ist der Spruch vielleicht überflüssig oder sogar irritierend?
- break;
- }
- }
- p->arrayLaenge = c;
- fclose(datei);
- printf("Es wurden %d Wertepaare aus %s geladen.\n", p->arrayLaenge, dateipfad);
- }
- void DatenBerechnen(struct Punkte *p)
- {
- double summeXi = 0.0;
- double summeYi = 0.0;
- double FlaechenInhalt;
- int zaehler = 0;
- while (zaehler < p->arrayLaenge) //Rechnung nach Gauss Elling Verfahren
- {
- if (zaehler + 1 == p->arrayLaenge) {
- summeXi += p->x[0] * p->y[zaehler];
- summeYi += p->x[zaehler] * p->y[0];
- }
- else {
- summeXi += p->x[zaehler + 1] * p->y[zaehler];
- summeYi += p->x[zaehler] * p->y[zaehler + 1];
- }
- zaehler++;
- }
- FlaechenInhalt = (summeXi - summeYi) / 2;
- printf("\nFlaecheninhalt = %lf\n", FlaechenInhalt);
- }
- void DatenGenerieren(struct Punkte *p)
- {
- // Info: das sind die Beispielpunkte vom Aufgabenzettel
- p->x[0] = 2;
- p->y[0] = 1;
- p->x[1] = 3;
- p->y[1] = 8;
- p->x[2] = 5;
- p->y[2] = 7;
- p->x[3] = 6;
- p->y[3] = 4;
- p->arrayLaenge = 4;
- printf("Info: Es wurden %d Testdaten generiert. Der Flächeninhalt sollte 15 sein.\n", p->arrayLaenge);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement