Advertisement
TRToC

NielsC_Aufgabe1_SO

Oct 22nd, 2023
715
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.13 KB | Source Code | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS 1 // nur für Microsoft VS weil der sonst rum nervt
  2. #include <stdio.h>
  3. #include <locale.h>
  4. #include <stdbool.h>
  5. #include <string.h>
  6.  
  7. // Defines
  8. #define MAXPUNKTE 256
  9. #define PATH_MAX    4096    /* maximale Länge von einem Linux-Path für eine Datei, inklusive dem NULL am Ende */
  10.  
  11. // Structs: unsere Keks-Stanzform
  12. struct Punkte
  13. {
  14.     double x[MAXPUNKTE];
  15.     double y[MAXPUNKTE];
  16.     int arrayLaenge;
  17. };
  18.  
  19. // Prototypen
  20. void MenuAusgabe();
  21. 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.
  22. void DatenAufnehmen(struct Punkte *p);
  23. void DatenAusgeben(struct Punkte *p);
  24. void DatenKorrigieren(struct Punkte *p);
  25. void DatenSpeichern(struct Punkte *p);
  26. void DatenLaden(struct Punkte *p);
  27. void DatenBerechnen(struct Punkte *p);
  28. void DatenGenerieren(struct Punkte *p);
  29. void LeseStringWert(char *ziel, int maxLaenge); // Hilfsfunktion weil scanf echt nervt bei Texteingabe
  30.  
  31. int main(void)
  32. {
  33.     setlocale(LC_ALL, "de_DE"); // Sprache auf Deutsch stellen/ damit kommer und Punkte angepasst werden
  34.     struct Punkte meinePunkte; // unser einziger wahrer Keks den wir gestanzt haben
  35.  
  36.     Menu(&meinePunkte);
  37.  
  38.     return 0; // Rückgabewert 0 an das Aufrufende Programm zurück geben: d.h. wir haben keinen gelben Schnee gegessen
  39. }//main ende
  40.  
  41.  
  42. //MenuAusgabe ist eine Funktion die Ausgabe des Standards Menus aus gibt
  43. void MenuAusgabe()
  44. {
  45.     printf("\n");
  46.     printf("Berechnung eines Flächeninhalts\n");
  47.     printf("===============================\n");
  48.     printf("(1) Daten aufnehmen\n");
  49.     printf("(2) Daten ausgeben\n");
  50.     printf("(3) Daten korrigieren\n");
  51.     printf("(4) Daten speichern\n");
  52.     printf("(5) Daten laden\n");
  53.     printf("(6) Flächeninhalt ermitteln\n");
  54.     printf("(7) Testdaten generieren\n"); // todo: kann in der Endversion weg
  55.     printf("(0) Ende [ESC]\n");
  56.     printf("Treffen Sie eine Wahl und bestätigen Sie mit Enter:\n");
  57. }
  58.  
  59. void Menu(struct Punkte *p) // bei *p ist unser Keks. Wir werden ihn an alle Funktionen weiter geben die den Keks bearbeiten sollen.
  60. {
  61.     int eingabe;
  62.     MenuAusgabe();  // Die Menu-Ansicht wird ausgegeben
  63.     do
  64.     {
  65.         scanf("%d", &eingabe); // todo: das ist super unsicher hier, bitte keine Buchstaben oder so eingeben
  66.         if (eingabe == 1)
  67.         {
  68.             DatenAufnehmen(p);    //ausführen
  69.             MenuAusgabe();  // Die Menu-Ansicht wird ausgegeben
  70.         }
  71.         else if (eingabe == 2)
  72.         {
  73.             DatenAusgeben(p);       //ausführen
  74.             MenuAusgabe();  // Die Menu-Ansicht wird ausgegeben
  75.         }
  76.         else if (eingabe == 3)
  77.         {
  78.             DatenKorrigieren(p); //ausführen
  79.             MenuAusgabe();  // Die Menu-Ansicht wird ausgegeben
  80.         }
  81.         else if (eingabe == 4)
  82.         {
  83.             DatenSpeichern(p);   //ausführen
  84.             MenuAusgabe();  // Die Menu-Ansicht wird ausgegeben
  85.         }
  86.         else if (eingabe == 5)
  87.         {
  88.             DatenLaden(p);       //ausführen
  89.             MenuAusgabe();  // Die Menu-Ansicht wird ausgegeben
  90.         }
  91.         else if (eingabe == 6)
  92.         {
  93.             DatenBerechnen(p);   //ausführen
  94.             MenuAusgabe();  // Die Menu-Ansicht wird ausgegeben
  95.         }
  96.         else if (eingabe == 7)
  97.         {
  98.             DatenGenerieren(p); //ausführen
  99.             MenuAusgabe();  // Die Menu-Ansicht wird ausgegeben
  100.         }
  101.     } while (eingabe != 0);     //Programm beenden
  102.  
  103.     /*Die Funktion Menu() beruht auf dem Prenzip eines endlichen Automatens.
  104.     es Läuft eine Schleife durch und wenn ein Menupunkt ausgewählt wird,
  105.     wenden die Funktion in dem Menupunkt ausgeführt. danach geht die Schleife weiter
  106.     und man Befindet sich wieder im Hauptmenu.
  107.  
  108.     Da die Ausgabe immer wieder kommt ist sie in der Funktion MenuAusgabe() zusammen
  109.     gefasst
  110.     */
  111. }// Menu beendet
  112.  
  113. void DatenAufnehmen(struct Punkte *p)
  114. {
  115.     bool schleife = true;                                                   // Breaker für die schleife
  116.     int zaehler = 0;
  117.     double inputX;
  118.     double inputY;
  119.     double tmpX[MAXPUNKTE];                                                 //temporaere  XY-Werte
  120.     double tmpY[MAXPUNKTE];
  121.     printf("Um abzuschließen bitte den ersten Punkt erneut angeben.");
  122.     while (schleife) {
  123.         printf("Geben sie bitte Punkt %d X an:", zaehler + 1);
  124.         scanf("%lf", &inputX); while (getchar() != '\n') {}                       //ggf auf zahlen gegeprüfen und dann mit getchar arbeiten;     ARBEIT!!!!
  125.  
  126.         tmpX[zaehler] = inputX;                                             //Inhalt von X an denn Array übergeben
  127.  
  128.         printf("Y an:");
  129.         scanf("%lf", &inputY); while (getchar() != '\n') {}                      //ggf auf zahlen gegeprüfen und dann mit getchar arbeiten;     ARBEIT!!!!
  130.  
  131.         tmpY[zaehler] = inputY;                                             //Inhalt von Y an denn Array übergeben
  132.  
  133.         if ((tmpX[0] == inputX && tmpY[0] == inputY && zaehler > 0))         //Fehlerabfangen
  134.         {
  135.             if (zaehler < 4)                                                 //Fehlerabfangen eine flaeche hat min 3 Punkte
  136.             {
  137.                 printf("Zu weing werte bitte Versuchen sie es erneut.\n");
  138.             }
  139.             schleife = false;
  140.         }
  141.         if (zaehler == MAXPUNKTE - 1)                                         //Zahlen begrenzen um Fehler zu vermeiden          
  142.         {
  143.             schleife = false;
  144.             printf("Leider haben sie zuviele Zahlen eingegben\n");
  145.         }
  146.         zaehler++;
  147.         printf("Punkt %d: X:%2f Y:%2f\n", zaehler, inputX, inputY);            //Ausgabe welche Zahlen eingebenben wurden
  148.     }
  149.     int zaehler2 = 0;
  150.     while (zaehler2 < zaehler) {
  151.         p->x[zaehler2] = tmpX[zaehler2];                                       //in X[] und Y[]  soll der inhalt von tmpX[] und tmpY[] und dabei soll Punkt: weggekürzt werden
  152.         p->y[zaehler2] = tmpY[zaehler2];
  153.         zaehler2++;
  154.     }
  155.     tmpX[zaehler] = '\n';
  156.     tmpY[zaehler] = '\n';
  157.     p->arrayLaenge = zaehler;                                                         //Anzahl der Eingaben Global weiter geben.
  158. }
  159.  
  160. void DatenAusgeben(struct Punkte *p)
  161. {
  162.  
  163.     if (p->arrayLaenge > 0)
  164.     {
  165.         int zaehler = 0;
  166.         printf("(2) Daten ausgeben:\n");        //benutzerinfo  
  167.         printf("--------------\n");
  168.         while (zaehler < p->arrayLaenge)            //Solange in arraylaenge inhalt ist wird dieser ausgebenen
  169.         {
  170.             printf("%d. Punkt: x:%lf\n", zaehler + 1, p->x[zaehler]);     //Ausgabe "NR." Punkt: x: "Eingabe x"
  171.             printf("           y:%lf\n", p->y[zaehler]);                 //Ausgabe y:"Eingabe y"
  172.             zaehler++;
  173.         }
  174.         printf("--------------\n");
  175.         printf("Bitte Enter zum Fortfarhen:\n");
  176.  
  177.         while (getchar() != '\n') {}                //wenn Enter gedrückt wird faehrt das Programm fort
  178.  
  179.     }
  180.     else {
  181.         printf("Leider sind noch keine Daten vorhanden:\n\n\n\n");  //sollten keine Daten vorhanden sein
  182.     }
  183. }//ende DatenAusgeben
  184.  
  185. void DatenKorrigieren(struct Punkte *p)
  186. {
  187.     if (p->arrayLaenge > 0) {
  188.         printf("Bitte geben sie den Punkt an den sie bearbeiten wollen.\n");
  189.         printf("Zahlen zwischen 1 und %d sind Zulässig\n", p->arrayLaenge - 1);  //Benutzerinfo
  190.         int inputBearbeiten;
  191.         scanf("%d", &inputBearbeiten);           //abfrage welcher Datensatz veraendert werden soll
  192.         if (inputBearbeiten <= p->arrayLaenge - 1) {   //Vergleich ob der datensatz vorhanden ist
  193.             double xNeu;                        //Zwischenspeicher für X
  194.             double yNeu;                        //Zwischenspeicher für Y
  195.             printf("Alt X war %f.\nBitte geben sie X neu an:\n", p->x[inputBearbeiten - 1]);
  196.             scanf("%lf", &xNeu);
  197.             printf("Alt Y war %f.\nBitte geben sie Y neu an:\n", p->y[inputBearbeiten - 1]);
  198.             scanf("%lf", &yNeu);
  199.             printf("xNeu = %f", xNeu);
  200.             p->x[inputBearbeiten - 1] = xNeu;      //denn alten X-Wert mit dem neuen überschreiben
  201.             p->y[inputBearbeiten - 1] = yNeu;      //denn alten Y-Wert mit dem neuen überschreiben
  202.             if (inputBearbeiten == 1)
  203.             {
  204.                 p->x[p->arrayLaenge - 1] = xNeu;          //wenn der Erste Wert veraendert werden soll muss der letzte auch geaender werden
  205.                 p->y[p->arrayLaenge - 1] = yNeu;
  206.             }
  207.  
  208.  
  209.             printf("--------------\n");
  210.         }
  211.         else {
  212.             printf("Die eingabe war zu Groß.\n");  //Eingabe ist begrenzt
  213.         }
  214.  
  215.     }
  216.     else {
  217.         printf("Leider sind noch keine Daten vorhanden:\n\n\n\n");      //DatenVorhanden ist noch false
  218.     }
  219.  
  220. }//ende DatenKorrigieren
  221.  
  222. // Info: eine sehr hilfreiche Funktion. persönliche Meinung. Ich hasse scanf()!
  223. void LeseStringWert(char *ziel, int maxLaenge) {
  224.     while (getchar() != '\n'); // LeseBuffer löschen. keine Ahnung ob das hier nötig ist. Sicher ist sicher.
  225.     fgets(ziel, maxLaenge, stdin);
  226.  
  227.     // Entferne das newline-Zeichen am Ende des Strings
  228.     size_t laenge = strlen(ziel);
  229.     if (laenge > 0 && ziel[laenge - 1] == '\n') {
  230.         ziel[laenge - 1] = '\0';
  231.     }
  232. }
  233.  
  234.  
  235. void DatenSpeichern(struct Punkte *p)
  236. {
  237.     printf("\n");
  238.     printf("(4) Daten speichern:\n");
  239.     printf("--------------------\n");
  240.     printf("Pfadname (Default: koord.txt):");
  241.  
  242.     char dateipfad[PATH_MAX];
  243.     LeseStringWert(dateipfad, PATH_MAX);
  244.  
  245.     if (dateipfad[0] == '\0') {
  246.         strcpy(dateipfad, "koord.txt");
  247.     }
  248.  
  249.     FILE *datei = fopen(dateipfad, "w");
  250.  
  251.     if (datei == NULL) {
  252.         printf("FEHLER: Die Datei %s konnte nicht zum Schreiben geöffnet werden.\n", dateipfad);
  253.         return;
  254.     }
  255.  
  256.     for (int i = 0; i < p->arrayLaenge; i++) {
  257.         fprintf(datei, "%.2lf %.2lf\n", p->x[i], p->y[i]);
  258.     }
  259.  
  260.     fclose(datei);
  261.     printf("Es wurden %d Wertepaare in %s gespeichert.\n", p->arrayLaenge, dateipfad);
  262.  
  263. }
  264.  
  265.  
  266. void DatenLaden(struct Punkte *p)
  267. {
  268.     printf("\n");
  269.     printf("(5) Daten laden:\n");
  270.     printf("--------------------\n");
  271.     printf("Pfadname (Default: koord.txt):");
  272.  
  273.     char dateipfad[PATH_MAX];
  274.     LeseStringWert(dateipfad, PATH_MAX);
  275.  
  276.     if (dateipfad[0] == '\0') {
  277.         strcpy(dateipfad, "koord.txt");
  278.     }
  279.  
  280.     FILE *datei = fopen(dateipfad, "r");
  281.  
  282.     if (datei == NULL) {
  283.         printf("FEHLER: Die Datei %s konnte nicht zum Lesen geöffnet werden.\n", dateipfad);
  284.         return;
  285.     }
  286.  
  287.     int c = 0;
  288.     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
  289.         c++;
  290.         if (c >= MAXPUNKTE) {
  291.             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?
  292.             break;
  293.         }
  294.     }
  295.    
  296.     p->arrayLaenge = c;
  297.     fclose(datei);
  298.  
  299.     printf("Es wurden %d Wertepaare aus %s geladen.\n", p->arrayLaenge, dateipfad);
  300.  
  301. }
  302.  
  303.  
  304. void DatenBerechnen(struct Punkte *p)
  305. {
  306.     double summeXi = 0.0;
  307.     double summeYi = 0.0;
  308.     double FlaechenInhalt;
  309.     int zaehler = 0;
  310.     while (zaehler < p->arrayLaenge)                                            //Rechnung nach Gauss Elling Verfahren
  311.     {
  312.         if (zaehler + 1 == p->arrayLaenge) {
  313.             summeXi += p->x[0] * p->y[zaehler];
  314.             summeYi += p->x[zaehler] * p->y[0];
  315.         }
  316.         else {
  317.             summeXi += p->x[zaehler + 1] * p->y[zaehler];
  318.             summeYi += p->x[zaehler] * p->y[zaehler + 1];
  319.         }
  320.         zaehler++;
  321.     }
  322.     FlaechenInhalt = (summeXi - summeYi) / 2;
  323.     printf("\nFlaecheninhalt = %lf\n", FlaechenInhalt);
  324. }
  325.  
  326.  
  327. void DatenGenerieren(struct Punkte *p)
  328. {
  329.     // Info: das sind die Beispielpunkte vom Aufgabenzettel
  330.     p->x[0] = 2;
  331.     p->y[0] = 1;
  332.     p->x[1] = 3;
  333.     p->y[1] = 8;
  334.     p->x[2] = 5;
  335.     p->y[2] = 7;
  336.     p->x[3] = 6;
  337.     p->y[3] = 4;
  338.     p->arrayLaenge = 4;
  339.     printf("Info: Es wurden %d Testdaten generiert. Der Flächeninhalt sollte 15 sein.\n", p->arrayLaenge);
  340.  
  341. }
  342.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement