Verbrauchsrechner selber "bauen"



  • Da ist nichts magisches. Immer der Reihe nach.

    if (Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "r")) 
    { while(4 == fscanf(Verbrauchsrechner , "%99[^;];%99[^;];%i;%i", marke, modell, &kilometerstand, &tank)) 
      { printf("Marke: %s\nModell: %s\nKilometerstand: %i\nTank: %i\n", marke, modell, kilometerstand, tank);
        Andere Sachen mit den Variablen ... Berechnungen, ablegen ins Array, ...
      }
      fclose (Verbrauchsrechner);
    }
    


  • if (Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "r")) {
    
    		 while(5 == fscanf(Verbrauchsrechner , "%i;%i;%i;%i;%99[^;]", &Kilometerstand, &Tankinhalt,  &Letzterverbrauch, &Durchschnittsverbrauch, Datum)) {
    
             printf("Kilometerstand %s\nTankinhalt: %s\nLetzter Verbrauch %i\nDurchschnittsverbrauch: %i\nDatum: %s", Kilometerstand, Tankinhalt, Letzterverbrauch, Durchschnittsverbrauch, Datum);
    
    		 printf("Neuer Kilometerstand:\n");
    		 scanf("%lf", &KilometerstandNeu);
    		 fprintf (Verbrauchsrechner, "%f;", KilometerstandNeu);
    
    		 printf("Geben Sie bitte nun die Fuellmenge ein:\n");
    		 scanf("%lf", &Tankinhalt);
    		 fprintf (Verbrauchsrechner, "%f;", Tankinhalt);
    
    		 // Letzter Verbrauch
    
    		 Letzterverbrauch = KilometerstandNeu - Kilometerstand / Tankinhalt;
    
    		 fprintf(Verbrauchsrechner, "%f;", Letzterverbrauch);
    
    		 // Gesamtverbrauch
    
    	//	 double Durchschnittsverbrauch =  Wie kann ich da den neustens KM Stand herholen, den ersten KM Stand abziehen und dann durch die Summe aller Tankinhalte dividieren?
    
    		 fprintf(Verbrauchsrechner, "%f;", Durchschnittsverbrauch); 
    
    		 printf("Bitte geben Sie das heutige Datum ein: \n");
    		 scanf("%s", &Datum);
    		 fprintf (Verbrauchsrechner, "%s;", Datum);
    
    		 fclose (Verbrauchsrechner);  
    
    		 }}
    

    Leider kommt da gar nichts, wenn ich das ausführe. Kann ich nicht nachvollziehen irgendwie...


  • Mod

    C-Tabaluga schrieb:

    Kann ich nicht nachvollziehen irgendwie...

    Dann benutz einen Debugger oder andere Methoden, um das Problem nachzuvollziehen (Testausgaben oder ähnliches). Wir können so ein Problem auch nicht nachvollziehen, wenn du uns nicht alles zeigst, was dafür gebraucht wird.



  • Ich benutz das bei vielen ungeliebte Visual Studio, also hab einen Debugger und der sagt mir, wenn ich jetzt nur mal einlesen will:

    "Zugriffsverletzung beim Lesen an Position 0x459c4000."

    Ich will erst mal verstehen, wie das mit dem einlesen überhaupt funktioniert und hab deshalb den kompletten Code im Moment so:

    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    
    int main () {
    
    	 double Tankinhalt = 0;
         double Kilometerstand = 0;
    	 double KilometerstandNeu = 0;
    	 double Letzterverbrauch = 0;
    	 double Durchschnittsverbrauch = 0;
    	 double Verbrauch = 0;
    	 char Datum[14];
    
    	 FILE *Verbrauchsrechner;
    
    	 if (Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "r")) {
    
    	     Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "a+");
    
    		 fscanf(Verbrauchsrechner , "%f;%f;%f;%f;%99[^;]", &Kilometerstand, &Tankinhalt,  &Letzterverbrauch, &Durchschnittsverbrauch, Datum); // i ist glaube ich für mich die falsche formatierung, weil ich ja ein double will, also wsh d
    
    		 printf("Kilometerstand %s\nTankinhalt: %s\nLetzter Verbrauch %i\nDurchschnittsverbrauch: %i\nDatum: %s", Kilometerstand, Tankinhalt, Letzterverbrauch, Durchschnittsverbrauch, Datum);
    
    		 printf("Neuer Kilometerstand:\n");
    		 scanf("%lf", &KilometerstandNeu);
    		 fprintf (Verbrauchsrechner, "%.2f;", KilometerstandNeu);
    
    		 printf("Geben Sie bitte nun die Fuellmenge ein:\n");
    		 scanf("%lf", &Tankinhalt);
    		 fprintf (Verbrauchsrechner, "%.2f;", Tankinhalt);
    
    		 // Letzter Verbrauch
    
    		 Letzterverbrauch = KilometerstandNeu - Kilometerstand / Tankinhalt;
    
    		 fprintf(Verbrauchsrechner, "%.2f;", Letzterverbrauch);
    
    		 // Gesamtverbrauch
    
    	//	 double Durchschnittsverbrauch =  Wie kann ich da den neustens KM Stand herholen, den ersten KM Stand abziehen und dann durch die Summe aller Tankinhalte dividieren?
    
    		 fprintf(Verbrauchsrechner, "%.2f;", Durchschnittsverbrauch); 
    
    		 printf("Bitte geben Sie das heutige Datum ein: \n");
    		 scanf("%s", &Datum);
    		 fprintf (Verbrauchsrechner, "%s;", Datum);
    
    		 fclose (Verbrauchsrechner);  
    
    		 }
    
    	 else {
    
    	 Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "w");
    	 printf("Willkommen zum Verbrauchsrechner, bitte legen Sie ein Fahrzeug an: \n");
    
    	 printf("Kilometerstand: \n");
    	 scanf("%lf", &Kilometerstand);
    	 fprintf (Verbrauchsrechner, "%.2f;", Kilometerstand);
    
    	 printf("Tankinhalt: \n");
    	 scanf("%lf", &Tankinhalt);
    	 fprintf (Verbrauchsrechner, "%.2f;", Tankinhalt);
    
    	 //beim ersten Start NULL anlegen für die Verbräuche 
    	 fprintf (Verbrauchsrechner, "%.2f;");
    	 fprintf (Verbrauchsrechner, "%.2f;");
    
    	 printf("Bitte geben Sie das heutige Datum ein: \n");
    	 scanf("%s", &Datum);
         fprintf (Verbrauchsrechner, "%s;\n", Datum);
    
    	 fclose (Verbrauchsrechner);  
    
    	 }
    
    	 getch();
    	 return 0;
    	}
    

    Ich bekomme 3 mal "Schlechtes Ptr".

    Was mich etwas stört beim debuggen mit Visual Studios ist das er dann eine andere Klasse öffnet und da etwas meckert, womit ich gar nichts anfangen kann... Wobei ich ansonsten mit C und Visual Studio einigermaßen zurecht gekommen bin...


  • Mod

    Guck dir nochmal an, wie scanf genau funktioniert. Der Formatstring von scanf ist nicht das genaue Gegenstück von printf. Außerdem machst du komische Sachen mit deinen Dateien. Was sollen Zeilen 19-22 bewirken? Was immer du denkst, sie tun es wahrscheinlich nicht.



  • Schalte alle Warnungen an. (in den Projekt-Einstellungen /Optionen Compiler)
    Beachte die Warnungen.*
    Behebe die Ursache dafür.

    *Als Ausnahme gilt nur, wenn da steht du solltest scanf_s/fscanf_s nehmen.
    Diese Warnung darfst du übersehen.



  • Also Zeile 19-22:

    Soll checken, ob bereits eine Datei vorhanden ist und wenn sie zu lesen ist, soll sie zum schreiben geöffnet werden und das, was bisher drin steht, soll ausgegeben werden.

    Wegen der Formatierung, selbst wenn ich statt %f %d nehme, passiert nicht das gewünschte.

    Ich hab mir die Formatierung von scanf schon angesehen, aber egal, was ich einsetze, der gibt mir nichts aus, auch wenn eine Textdatei mit Inhalt existiert.

    MfG


  • Mod

    C-Tabaluga schrieb:

    Also Zeile 19-22:

    Soll checken, ob bereits eine Datei vorhanden ist und wenn sie zu lesen ist, soll sie zum schreiben geöffnet werden

    Hier mal Stopp. Prüf mal, ob es das wirklich tut.

    Wegen der Formatierung, selbst wenn ich statt %f %d nehme, passiert nicht das gewünschte.

    Ich weiß nicht, was ich dazu noch sagen soll. Rätst du nur?

    Ich hab mir die Formatierung von scanf schon angesehen,

    Wo hast du das gelesen? Wie kommst du von dort auf %d?



  • Ich hab das daher gezogen: http://www.cplusplus.com/reference/cstdio/fscanf/

    Ich denke, laut der Seite wäre ich ja mit f bestens beraten.

    if (Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "r")) {
    
    	     Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "a+");
    
    //		 fscanf(Verbrauchsrechner , "%f;%f;%f;%f;%99[^;]", &Kilometerstand, &Tankinhalt,  &Letzterverbrauch, &Durchschnittsverbrauch, Datum); // i ist glaube ich für mich die falsche formatierung, weil ich ja ein double will, also wsh d
    
    	//	 printf("Kilometerstand %s\nTankinhalt: %s\nLetzter Verbrauch %i\nDurchschnittsverbrauch: %i\nDatum: %s", Kilometerstand, Tankinhalt, Letzterverbrauch, Durchschnittsverbrauch, Datum);
    
    		 printf("Neuer Kilometerstand:\n");
    		 scanf("%lf", &KilometerstandNeu);
    		 fprintf (Verbrauchsrechner, "%.2f;", KilometerstandNeu);
    

    Wenn ich fscanf und das dazugehörige printf weglasse, schreibt er neue Daten in die Datei.

    Also das funktioniert. Nur scheiter ich immer noch am Datei auslesen... ich setz mich ne halbe Stunde, Stunde hin und probier rum und komm nicht weiter und dann verlässt mich irgendwie auch schnell der Mut - das war mit Java/C# nicht sooo schwer, wobei ich C an sich ja schon ganz interessant finde...



  • Jetzt lass doch endlich mal die verschissenen Zeile mit dem "a+" weg!

    Hast du immer noch nicht kapiert, dass die total falsch ist?



  • Ne, habe ich nicht verstanden, weil ich durch die Zeile ja was reinschreiben konnte in die txt Datei...



  • Du willst doch aber was daraus lesen.



  • Schon, aber danach will ich ja neue Daten einschreiben. Tut mir leid, dass ich mich so saublöd anstelle, aber ich komm nicht drauf.



  • Alles der Reihe nach.
    - Datei zum Lesen öffnen
    - Daten auslesen
    - Datei schließen ⚠
    - Datei zum Schreiben/Anhängen öffnen
    - Daten schreiben
    - Datei schließen


  • Mod

    C-Tabaluga schrieb:

    Also das funktioniert. Nur scheiter ich immer noch am Datei auslesen... ich setz mich ne halbe Stunde, Stunde hin und probier rum und komm nicht weiter und dann verlässt mich irgendwie auch schnell der Mut - das war mit Java/C# nicht sooo schwer, wobei ich C an sich ja schon ganz interessant finde...

    Da C in Sachen Dateihandling nicht so großartig anders ist: Wie würdest du es denn in C# machen? Schreib ruhig mal ein kleines Programm (und teste, ob es auch wirklich funktioniert!). Fällt dir was auf bezüglich der Art und Weise, wie du die Datei öffnest?



  • if (Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "r")) {
    
    	     Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "r");
    
    		 fscanf(Verbrauchsrechner , "%f;%f;%f;%f;%99[^;]", &Kilometerstand, &Tankinhalt,  &Letzterverbrauch, &Durchschnittsverbrauch, Datum); // i ist glaube ich für mich die falsche formatierung, weil ich ja ein double will, also wsh d
    
    		 printf("Kilometerstand %s\nTankinhalt: %s\nLetzter Verbrauch %i\nDurchschnittsverbrauch: %i\nDatum: %s", Kilometerstand, Tankinhalt, Letzterverbrauch, Durchschnittsverbrauch, Datum);
    
    		 fclose (Verbrauchsrechner);  
    
    		 Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "a+");
    
    		 printf("Neuer Kilometerstand:\n");
    		 scanf("%lf", &KilometerstandNeu);
    		 fprintf (Verbrauchsrechner, "%.2f;", KilometerstandNeu);
    
    //..........................
    

    Da sollte die Reihenfolge nun stimmen.

    Bei C# wären die Möglichkeiten ja simpler, meiner Meinung nach, ich würd nen String erstellen bzw. ne Variable, der ich den Text bzw die Zahl zuteilen kann per StreamReader und z.B. mit ReadToEnd() arbeiten... aber das tut für C nichts zur Sache... ich finde einfach den Fehler nicht beim einlesen, weil wenn ich mit den C++ Preferences vergleiche und das parallel so machen will, kommt meine Version dabei raus, aber irgendwo hakt das noch...



  • weglassen ist ändern, aber ändern ist nicht unbedingt weglassen.

    Was machen die Zeilen 1 und 3?
    Vor der Antwort nochmal darüber nachdenken.

    Ist Kilometerstand eine Variable vom Typ float ?
    Denn scanf speichert bei %f die Daten in einer float -Variablen.

    Falls du jetzt der Meinung bist, die andern Formatspecifier hast du schon probiert und es hat auch nicht funktioniert, dann lass dir sagen, es lag nicht alleine an den Specifiern.

    Denn

    DirkB schrieb:

    Jetzt lass doch endlich mal die verschissenen Zeile mit dem "a+" weg!

    Hast du immer noch nicht kapiert, dass die total falsch ist?



  • if (Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "r")) // hier versuchst du die Datei zu öffnen! Wenn es gelungen ist, =>
     {
             Verbrauchsrechner = fopen ("Verbrauchsrechner.txt", "r"); // warum versuchst du hier die offene Datei ein 2tes mal zu öffnen??
    // Wenn das beim ersten mal nicht gelungen ist die Datei zu öffenen, warum soll das nun funktionieren??
    


  • War jetzt über die beiden Wochen anders beschäftigt, Zeit mal wieder zurück zu der Sache zu kommen.

    Ich dachte bisher, dass eine if Bedingung NUR überprüft, aber nicht gleichzeitig ein Befehl ist. Deshalb dachte ich, erst testen, ob sie vorhanden ist und dann den Befehl ausrufen, sie soll geöffnet werden...



  • Das fopen in denr Bedingung vom if wird ausgeführt. Wie soll denn if sonst an den Rückgabewert von fopen kommen?


Anmelden zum Antworten