fscanf Problem



  • Hi Community

    Ich habe folgendes Problem mit meinem C++ Programm:
    Ich habe ein Textdokument, die ersten 3 Zeilen enthalten nur allgemeine Informationen, ab Zeile 4 folgen Werte in diesem Schema:

    01-02-01 00:00:00 18560.000 0
    01-02-01 00:15:00 18720.000 0
    01-02-01 00:30:00 18000.000 0
    usw.

    Die ersten 3 Zeilen auslesen erfolgt ohne Probleme. Meine Frage jetzt wie kann ich dann die anderen zeilen auslesen, sodass ich mit den Werten in Spalte 3 rechnen kann?

    Hier mein bisheriger Code:

    #include "stdafx.h"
    #include <iostream>
    #include <fstream>
    #include <Windows.h>
    
    using namespace std;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	// Variabeln Menü
    	char input;
    	char programmauswahl[100];
    
    	printf("########## Analyse von Leistungsdaten ##########
    
    ");
    	// Programmstart
    	// Datei oeffnen
    	do {
    
    	    printf("[T]extdatei lesen und auswerten, [B]eenden - Bitte auswaehlen
    
    ");
    
    		// Menüauswahl
    		gets(programmauswahl);
    		input=programmauswahl[0];
    
    		// if T-d start
    		if(input=='T' || input=='t') { 
    
    				FILE *fp;
    				char datei[] = "C:\\Users\\Tony\\Desktop\\info_hausarbeit\\K_31307B.PWX";
    				fp=fopen(datei ,"r");
    				if(fp==NULL)
    
    				{
    					printf("
    
    ERROR: Datei konnte nicht geoeffnet werden!");
    					exit(-1);
    				}
    
    				std::cout << "
    Datei: " << datei << " - oeffnen erfolgreich" << std::endl;
    				Sleep(2000);
    				printf("-------------------------------------------------------------------------------
    ");
    
    				// Analyse starten
    
    				int i,n;
    				char speicher[3000];
    				double leistung[3000], status[3000], zeit[3000];
    				n=0;
    
    				//Kopfzeilen, Ort, etc
    				for(n=0;n<3;n++)
    				{
    					fgets(&speicher[n],3000,fp);
    				    printf("%s", &speicher[n]);
    				}
    				printf("-------------------------------------------------------------------------------
    
    ");
    
    				// Hauptanalyse
    				i=n+1;
    				// speicher[n] ist nun speicher[i] -> DATUM
    
    					while(fscanf(fp,"%s %s %lf %lf", &speicher[i], &zeit[i], &leistung[3000], &status[i])!=EOF)
    					{
    						printf("%s %s %lf %lf
    ", &speicher[i], &zeit[i], &leistung[i], &status[i]);
    						i++;
    					}
    
    				fclose(fp);
    
    		} // if T-t end
    
    	} while(input !='B' && input !='b'); //do-while end
    return 0;
    }
    

    Dabei sind das hier die "Problemzeilen":

    while(fscanf(fp,"%s %s %lf %lf", &speicher[i], &zeit[i], &leistung[3000], &status[i])!=EOF)
    {
    printf("%s %s %lf %lf\n", &speicher[i], &zeit[i], &leistung[i], &status[i]);
    i++;
    }
    

    Vielen Dank für eure Hilfe 🙂



  • Benutze C++-Filestreams.
    Überhaupt - was du da machst, ist C, nicht C++- unglaublich. Nur die Header sind aus C++.
    Korrigiere: Ein Header.



  • Bin grade noch dabei zu lernen, deshalb erstmal mit fscanf.
    Konstruktivere Beiträge fände ich besser 😉


  • Mod

    tooony schrieb:

    Bin grade noch dabei zu lernen, deshalb erstmal mit fscanf.

    Wenn du Autofahren lernen möchtest, übst du also wie man mit Schlittschuhen läuft?

    Ich bin mir nicht sicher, willst du C oder C++ machen? Bevor das nicht klar ist, kann man dich nicht vernünftig beraten und Hackers Ratschlag, dass man C und C++ nicht mischen sollte, bleibt bis dahin das einzige, was man dir raten kann.



  • Tut mir leider, bin da leider noch zu neu auf dem Gebiet.

    Könnt ihr mir sagen wo in meinem code hier c und c++ vermischt wurde?
    Und vlt einen Ansatz wie ich mit fscanf mein Problem lösen kann?


  • Mod

    tooony schrieb:

    Könnt ihr mir sagen wo in meinem code hier c und c++ vermischt wurde?

    #include "stdafx.h" // Irgendwelcher VS-Quatsch
    #include <iostream>  // C++
    #include <fstream>   // C++
    #include <Windows.h> // Irgendwelcher Windows-Quatsch
    
    using namespace std;  // C++
    
    int _tmain(int argc, _TCHAR* argv[])  // Irgendwelcher Windows- und VS-Quatsch
                    std::cout << "Datei: " << datei << " - oeffnen erfolgreich" << std::endl;   // C++
                    Sleep(2000);   // Windows
    

    Deine eigentliche Frage beantworte ich gleich, nach der nächsten Maus.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum C (C89 und C99) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    Der passende Formatstring sollte

    fscanf("%*s %*s %lf 0", &variable_fuer_dritten_wert);
    

    sein (ungetestet).

    Das wird dir aber alleine nicht viel nützen, da der Rest des Programms größtenteils Unsinn ist. Aber wie dir schon geschrieben wurde, solltest du wohl vielleicht erst einmal alles sauber in deine Zielsprache umschreiben (und deine Zielsprache vorher/dabei überhaupt mal richtig lernen!), dann ist man motivierter, dir zu helfen. An diesem Programm noch viel zu verbessern ist ziemlich vergebener Aufwand, da das Grundgerüst schon nicht stimmt.



  • Problem besteht leider weiterhin.



  • Edit: Shit, ich habe die Verschiebung nicht gemerkt 😃


  • Mod

    tooony schrieb:

    Problem besteht leider weiterhin.

    Du hast bisher noch nicht gesagt, was dein Problem überhaupt ist. Die Frage die ich beantwortet habe war, die du die dritte Spalte in einen arithmetischen Datentyp einlesen kannst.

    Die ganze Programmlogik drumherum ist, wie schon gesagt, auch sehr verdächtig. Da wird munter auf nicht-existierenden Speicher zugegriffen und was fscanf überhaupt zurück gibt oder wie man es sinnvoll in einer Schleife benutzt hast du wohl auch noch nie angeguckt.



  • @ SeppJ

    Inwiefern Unsinn?

    Mein Ziel soll es letztendlich sein die Werte der dritten Spalte auf einer Variablen zu hinterlegen und dann damit rechnen zu können. Genauer gesagt soll dann die prozentuale Veränderung von Wert zu Wert ermittelt werden.



  • @ SeppJ

    Das Ziel des Programms soll sein die Werte der 3. Spalte in einer Variablen zu speichern um später damit rechnen zu können. Genauer gesagt soll von Wert zu Wert die prozentuale Veränderung ermittelt werden.



  • @ SeppJ

    Das Ziel des Programms soll sein die Werte der 3. Spalte in einer Variablen zu speichern um später damit rechnen zu können. Genauer gesagt soll von Wert zu Wert die prozentuale Veränderung ermittelt werden.



  • tooony schrieb:

    int i,n;
                    char speicher[3000];   //  :warning: das ergibt einen String für bis zu 2999 Zeichen. 
                    double leistung[3000], status[3000], zeit[3000];
                    n=0;
    
                    //Kopfzeilen, Ort, etc
                    for(n=0;n<3;n++)
                    {
                        fgets(&speicher[n],3000,fp);  //  :warning: falsches verständnis von Strings in C
                        printf("%s", &speicher[n]);  
                    }
    ...
                    i=n+1;  //  :warning: überflüssig, da n hier schon 3 ist.
                    // speicher[n] ist nun speicher[i] -> DATUM
    
                        while(fscanf(fp,"%s %s %lf %lf", &speicher[i], &zeit[i], &leistung[3000], &status[i])!=EOF)
    //                                                                                     ^^^^Was ist das? :warning:
    

    char speicher[3000]; ergibt einen String für bis zu 2999 Zeichen.
    Das sind keine 3000 Strings.

    Wenn in deiner Datei Folgende 3 Zeilen stehen:

    Kopfzeilen
    Ort
    etc
    

    Dann steht in speicher:
    bei n = 0: "Kopfzeilen\n"
    bei n = 1: "KOrt\n"
    bei n = 2: "KOetc\n"

    Trenne mal einlesen und Ausgabe. Damm kannst du es sogar sehen.

    for(n=0;n<3;n++)
                        fgets(&speicher[n],3000,fp);  
                    for(n=0;n<3;n++)
                        printf("n = %d: %s\n", n, &speicher[n]);
    

    Nach dieser Schleife ist n = 3. da ist dann das +1 bei i = n+1 auch überflüssig.
    Warum bleibst du nicht bei n?

    Das &leistung[3000] beim fscanf hast du schon bemerkt?
    Da willst du in das Element 3000 von leistung schreiben. Das existiert aber gar nicht, da der Index nur bis 2999 geht.

    Hast du schon den Tipp von SeppJ umgesetzt?
    Das &variable_fuer_dritten_wert musst du natürlich an deine Variable anpassen. Etwa: &leistung[i]



  • Kurze Erklärung der 3000:
    In den ersten 3 Zeilen steht nur irgendwas, ohne ein schema...dabei ist zeike 2 komplett leer.
    Ab zeile 4 beginnt dann das schema wie folgt
    datum zeit wert wert2
    Es handelt sich dann hierbei um knapp 3000 solcher einträge. und von wert zu wert soll die prozentusle verändrrung berechnet werden.


  • Mod

    Warum musst du die Werte dann überhaupt abspeichern, wenn dich doch nur immer der aufeinander folgende Werte interessieren?



  • Weil im Anschluss dann alle Werte in ein neues Textdokument übernommen werden, nur das halt eine weiter Spalte dazukommt, inder die prozentuale Veränderung steht.

    Ich geb zu, ich bin grade sehr verwirrt.



  • Dann reicht es doch aus, sich den vorletzten Wert zu merken.

    Pseudo-

    AlterWert = 0
    
    Solange noch Zeilen in der Datei sind
    |  Zeile einlesen, Wert ermitteln
    |  Abweichung zu AlterWert berechnen.
    |  Zeile und Abweichung ausgeben
    |  AlterWert = Wert
    

    Dann kannst du auch Dateien mit Millionen Zeilen bearbeiten, da du nur die aktuelle Zeile und den letzten Wert im Speicher hast.



  • Vielen Dank für deine Hilfe & die schnellen Antworten!
    Ich werd das dann gleich mal probieren.



  • FILE *f = fopen("bla.txt","r");
    if( f )
    {
      double wert3;
      char zeile[1000]; /* Zeilenpuffer */
      while( fgets(zeile,1000,f) )
        if( 1==sscanf(zeile,"%*s%*s%lf",&wert3) ) /* nur wenn 3. "Wort" vorhanden und als double interpretierbar ist */
          printf("%f\n",wert3);
      fclose(f);
    }
    

Anmelden zum Antworten