Zahlen einer Liste aufsummieren



  • Hallo Allerseits,
    ich stehe schon seit geraumer Zeit vor einem Problem und weiß nicht, wie ich es in C lösen soll:
    ich habe eine Datei Zahlen.txt mit einer Liste von Floating-Point Zahlen, die ich aufaddieren muss. In der ersten Zeile steht noch eine Überschrift, die übersprungen werden muss. Das Ergebnis soll einfach auf der Konsole ausgegeben werden.
    Ich habe nun schon ein bischen hier im Forum gesucht und bin auf ein ähnliches Problem http://www.c-plusplus.net/forum/301040-full gestoßen, aber das trifft es nicht ganz so, wie ich es brauche. Daher bitte ich um eure Hilfe.

    Hier mal ein Auszug aus meiner Datei:

    %CPU
     96.8
     1.0
     0.6
     0.5
     0.3
     0.1
     0.0
      .
      .
      .
     0.0
    

    Die angegebenen Zahlen sollen aufsummiert werden.

    Schonmal Danke für eure Hilfe 🙂
    bucket



  • Summe = 0
    Datei öffnen und auf Erfolg prüfen
    Erste Zeile einlesen
    
    Solange es Werte gibt, diese einlesen
     Summe += Wert;
    
    Datei Schließen
    

    Jetzt die Masterfrage:
    "Mit welcher Standard-C-Funktion kann man Fließkommawerte aus einer Datei lesen?"



  • Hab gerade den anderen Thread zu Ende gelesen.
    Wenn du das Beispiel daraus den nicht geändert bekommst, wirst du hier keinen Erfolg haben.

    Hausaugaben werden hier nicht vorgemacht. Hilfe bekommst du.



  • Hallo Allerseits,
    da hab ich mich ein bischen schlecht ausgedrückt: mir ist schon klar, wie so ein Programm laufen muss, ich kenne mich nur zu wenig in C aus, um es zu realisieren.
    Das Programm ist auch keine Hausaufgabe sondern ein Teil eines privaten Projektes.

    Aber gut, dann halt ein paar detailiertere Fragen zu dem Code aus dem anderen Thread, denn den versteh ich leider nicht (jedenfalls nicht komplett):

    #include <stdio.h> 
    #include <stdlib.h> 
    
    void main() 
    { 
        int sum=0;  //Geht das auch mit double?
        FILE *strahl;    //Was bedeutet *strahl? Ist das der Dateiname?
        char dateiname[67];  //sollte wohl nicht mehr benötigt werden
        int stelle;  //anscheinend auch nicht genutzt
        int hilf; 
    
        if ((strahl = fopen("Zahlen.txt","r")) == NULL)  //das hier ist alles klar.
        { 
            printf("\nFehler beim Öffnen!"); 
            exit(1); 
        } 
    
        fscanf(strahl,"%i",&hilf);  //hier wird aus der Datei eine Zahl gelesen und in hilf gespeichert, oder?
        while(!feof(strahl))
        { 
            sum+=hilf; 
            fscanf(strahl,"%i",&hilf);
        } 
        fclose(strahl); 
        printf("\nDie Summe beträgt %i.",sum); 
    }
    

    Das Problem welches ich habe ist: das Programm hier summiert einfach Werte auf, die hintereinander in der Datei stehen. Wie kann ich es ändern, dass es
    1. die Werte aus einer Liste akzeptiert (denn das klappte bei Tests mit einer Integer-Liste eben nicht)?
    2. floating-point Zahlen akzeptiert (klappte auch nicht)?

    Für Letzteres wollte ich einfach sum und hilf als double deklarieren, aber das hat nicht funktioniert. Hab da nur Fehlermeldungen bekommen. Das ist mein erster Versuch mit C... 😕
    Ich hoffe, mein Problem ist nun klarer geworden. 🙂



  • Ich würde das etwa so machen:

    #include <stddef.h>
    #include <stdio.h>
    
    /* file_sum rechnet die Summe der Zahlen in der übergebenen Datei aus.
     */
    double file_sum(FILE *fd) {
      double sum = 0.0;
      double d;
    
      /* Solange Zahlen aus der Datei gelesen werden können */
      while(1 == fscanf(fd, "%lf", &d)) {
        /* Summiere diese auf. */
        sum += d;
      }
    
      /* Wenn das Dateiende nicht erreicht wurde, ist noch etwas anderes als
       * Zahlen in der Datei.
       */
      if(!feof(fd)) {
        fputs("Warnung: Datei enthält nicht nur Zahlen.\n", stderr);
      }
    
      /* Ergebnis der Funktion ist die Summe. */
      return sum;
    }
    
    /* print_file_sum gibt die Summe der Zahlen in der Datei des übergebenen
     * Namens aus.
     */
    void print_file_sum(char const *filename) {
      /* Datei öffnen */
      FILE *fd = fopen(filename, "r");
    
      /* Und Fehlerprüfung. */
      if(fd != NULL) {
        /* Bei Erfolg file_sum aufrufen, Ergebnis ausgeben, Datei schließen. */
        printf("%f\n", file_sum(fd));
        fclose(fd);
      } else {
        /* Sonst meckern. */
        fprintf(stderr, "Konnte Datei %s nicht öffnen\n", filename);
      }
    }
    
    /* Hauptfunktion. Die ist so angelegt, dass man dem Programm mehrere Dateinamen
     * übergeben kann und der die Dateien der Reihe nach durchnudelt.
     */
    int main(int argc, char *argv[]) {
      int i;
    
      /* argc ist die Anzahl der Kommandozeilenbestandteile (Programmname + Parameter),
       * argv ein Stringarray, in dem diese Bestandteiel stehen.
       * argv[0] ist der Programmname, argv[1] bis argv[argc - 1] die Parameter.
       *
       * Also: Alle Parameter durch print_file_sum schieben.
       */
      for(i = 1; i < argc; ++i) {
        print_file_sum(argv[i]);
      }
    
      return 0;
    }
    


  • bucket schrieb:

    Das Problem welches ich habe ist: das Programm hier summiert einfach Werte auf, die hintereinander in der Datei stehen. Wie kann ich es ändern, dass es
    1. die Werte aus einer Liste akzeptiert (denn das klappte bei Tests mit einer Integer-Liste eben nicht)?
    2. floating-point Zahlen akzeptiert (klappte auch nicht)?

    1. scanf überliest in den meisten Fällen sog. Whitespace. Dazu gehören Leerzeichen, Tabulatoren und Form- / Linefeed.

    Also ist es egal ob die Zahlen in einer oder mehr Zeilen stehen.

    2. Dafür muss man den richtigen Formatspecifier wählen. Steht in jeder Referenz zu scanf . Z.B.: http://www.cplusplus.com/reference/cstdio/scanf/
    Für foat wäre das %f und für double %lf

    scanf hört mit dem einlesen auf, wenn es Zeichen findet, die nicht zum Formatspecifier passen. Bei Ganzzahlen (%i oder %d) gehört der Dezimalpunkt zu diesen Zeichen.
    Es hat bei dir nicht funktioniert, weil immer der 1. Dezimalpunkt vorgefunden wurde.

    Bei dem Beipiel von seldon fehlt noch das Überlesen der erste Zeile.


Anmelden zum Antworten