Messwertverarbeitung, Dateiarbeit, Ein-Auslesen von textdateien (CSV Datei), nutzung von fscanf



  • So, wollte mich erstaml für den Müll entschuldigen, den ich hier als Quellcode gepostet habe. Ich habe nun einige Stunden mit dem Stoff verbracht und mir ist jetzt klar geworden, das das nur nonsense war.
    Ich wusste letzte woche noch nicht mal was sequenzieller zugriff von textdateien bedeutet, ist mir jetzt klar geworden. die datei soll einfach nur von anfang bis ende gelesen/ geschrieben werden, ab einem bestimmten punkt auslesen/einlesen (wahlfreier zugriff) ist garnicht nötig.

    Ich habe in die quelldatei einige kommentare und fragen geschrieben.
    die quelldatei habe ich selber geschrieben (wie man wahrscheinlich auch sehen kann), bzw. in eine datei menüauswahl mit drei optionen habe ich meinen kram ergänzt. ich habe heute mit den ersten 3 menüpunkten verbracht. also einlesen, überschreiben, anfügen der zu verarbeitenden Datei.

    bin gerade an den anderen teilaufgaben des menüs und bitte da auch um anregeungen.

    die ergebnisse der berechnung sollen in eine protokolldatei geschrieben werden.
    das geht doch dann mit frintf (fp...)

    Danke im Voraus

    #include <stdio.h>
    #include <math.h>
    #include <conio.h>
    #include <eigene.h>
    
    void datei(char[]);          // nur zur besseren übersicht
    void datei_neu (char[]);	//  "    "		"		
    void datei_anfügen(char[]);  //"	"	"	"	"	"
    void lesen(char[]);	
    void Schreiben(char[]);
    void Anfügen(char[]);
    void Schwankungsbreite(char[]);
    void arithmetisches_Mittel(char[]);
    void Koeffizienten(char[]);
    void Vergleich_Trendgerade (char[]);
    
    void main (void)
    {	char name [30];
    	char wahl;
    	do
    	{
    	 clrscr();
    	 printf ("\nAnzeigen der Messwerte aus CSV-Datei....................................1\n");
    	 printf ("\nMesswerte in eine neue CSV-Datei schreiben..............................2\n");
    	 printf ("\nMesswerte in CSV-Datei anfuegen/ergaenzen...............................3\n");
    	 printf ("\nBerechnung und Ausgabe der Schwankungsbreite der Messwerte..............4\n");
    	 printf ("\nBerechnung und Ausgabe des arith. Mittels und der Standardabweichung....5\n");
    	 printf ("\nBerechnung und Ausgabe der Koeffizienten der Trendgeraden...............6\n");
    	 printf ("\nVergleich der tatsaechlichen Messwerte mit der Trendgeraden.............7\n\n");
    	 printf ("\nProgrammende............................................................E\n\n");
    	 wahl=getch();
    
    	 switch (wahl)
    	 {
    		case '1':datei(name);               // könnte man auch direkt in void lesen packen
    					lesen (name); break;
    		case '2':datei_neu (name);			// "	"					" void schreiben packen
    					Schreiben (name);break;
    		case '3':datei_anfügen (name);		// "			"			" void Anfügen packen
    					Anfügen (name);break;
    		case '4':Schwankungsbreite (name);break;
    		case '5':arithmetisches_Mittel (name); break;
    		case '6':Koeffizienten (name); break;
    		case '7':Vergleich_Trendgerade (name); break;
    		case 'e':												// erkennt beim programmende auch kleines 'e'
    		case 'E':break;											// würde auch mit toupper gehen	
    		default: printf ("\n\nFalsche Eingabe, bitte neu: ");
    		getch();
    
    	 }
      } while (wahl !='e' && wahl !='E');				// damit der beim 'e' und beim 'E' beendet
    }	
    
    void datei (char name [30])
    {	clrscr(); 
    	printf ("\nBitte Namen der einzulesenden CSV-Datei eingeben: ");
    	scanf ("%s",name);
    }
    
    void lesen (char name [30])
    {	float wert;
    	FILE *datei;
    	datei=fopen(name,"r");
    	if (datei)
    	{
    		clrscr();
    		do
    		{	fscanf(datei,"%f",&wert);
    			if (feof(datei)) break;
    				printf("%f\n",wert);
    		}	while (!feof(datei));
    			fclose(datei);
    	} else printf("\nDie Datei kann nicht gelesen werden");
    	getch();
    }
    
    void datei_neu (char name [30])
    {	clrscr(); 
    	printf ("\nBitte Namen der neuen CSV Datei eingeben: ");
    	scanf ("%s",name);
    }
    
    void Schreiben (char name [30])
    {	float wert;
    	char ant;
    	FILE *datei;
    	datei=fopen(name,"w");    // vorhandene Datei wird überschrieben
    	do
    	{ clrscr();
    	  printf("\nBitte eine reelle Zahl: ");
    	  scanf("%f",&wert);
    
    	  fprintf(datei,"%f ",wert);  // Leerzeichen(Blank) nach f. oder semikolon, sonst schreibt der die zahlen aneinander
    	  //fwrite (&wert,sizeof (float),1,datei);  // nicht für textdateien, nur für Binärdateien
    
    	  printf("\nNoch eine Zahl?");
    	  ant=getch();
    
    	} while (ant == 'j');
    
    	  fclose(datei);
    
    }
    
    void datei_anfügen (char name [30])
    {	clrscr(); 
    	printf ("\nBitte Namen der Datei eingeben, an die die Daten angefuegt werden sollen: \n\n");
    	scanf ("%s",name);
    }
    void Anfügen (char name [30])
    {	float wert;
    	char ant;
    	FILE *datei;
    	datei=fopen(name,"a+");
    	do
    	{ clrscr();
    	  printf("\nGeben Sie die Zahl ein, die angefuegt werden soll: ");
    	  scanf("%f",&wert);
    
    	  fprintf(datei,"%f ",wert);
    	  //fwrite (&wert,sizeof (float),1,datei);  // nicht für textdateien
    
    	  printf("\nNoch eine Zahl?");
    	  ant=getch();
    
    	} while (ant == 'j');
    
    	  fclose(datei);
    
    }
    
    void Schwankungsbreite(char name [30])
    {	clrscr(); 
    	printf ("\nBitte Namen der Datei eingeben, aus der die Messwerte gelesen werden sollen: \n\n");
    	scanf ("%s",name);
    }
    
    void arithmetisches_Mittel(char name [50])
    
    {	
    
    	float messwert [50];		// einzelne Messwerte, hier feld mit 50 werten
    	float ergebnis,summe;
    	int n,i;				// Anzahl der Messwerte; sollen aus datei kommen
    
    	clrscr();
    	printf ("\n\nBitte geben Sie die Datei an, aus der die Daten gelesen werden sollen: \n");
    	scanf ("%s",name);									// Problem mit Anzahl der einzulesenden Werte, 
    														//soll ja aus datei gelesen werden
    	float wert;
    	FILE *datei;
    	datei=fopen(name,"r");
    	if (datei)
    	{
    		clrscr();
    		do
    		{	fscanf(datei,"%f",&wert);
    			if (feof(datei)) break;
    				printf("%f\n",wert);
    		}	while (!feof(datei));
    			fclose(datei);           // datei darf doch erst nach berechnung geschlossen werden???
    	} else printf("\nDie Datei kann nicht gelesen werden");
    	getch();
    	//for (i=0;i<n;i++)
    	fscanf(datei,"%f ",&wert);      // einlesen der daten auf variable wert
    
    	summe=0;
    	for (i=0;i<n;i++)
    
    	{	
    	summe+=messwert[i];
    	ergebnis=summe/n;
    	}	
    	printf ("\nDas arithmetische Mittel betraegt: %.3f\n\n",ergebnis);// drei Nachkommastellen
    
    	float v[50],z,t,s;	// v=x-/x; z= Zwischenergebnis; t= z/(n-1); s=standardabweichung
    	int j;
    
    	for (j=0;j<n;j++)
    	z=0;
    	for (i=0;i<n;i++)
    	{
    	v[j]=messwert[i]-ergebnis;		// berechnung von v für jeden einzelnen Messwert
    
    	z=z+pow((v[j]),2);
    	}
    	t=z/(n-1);
    	s=sqrt(t);
    
    	printf("Die Standardabweichung betraegt: %f\n\n",s);
    
    	getch();
    }
    
    void Koeffizienten(char name [30])
    {
    }
    
    void Vergleich_Trendgerade(char name [30])
    {
    }
    
    void Export(char name [30])
    {
    }
    

    [code]



  • Schonmal im voraus: Menüs baut eigentlich kaum jemand ein, so etwas macht man optimalerweise mit Startparametern. (int argc, char *argv[]).

    Zeile 3: <conio.h> ist kein standard C.
    Zeile 6 etc.: Ich mag nur englisch - gibt's aber viele Meinungen zu 😃
    Zeile 18: main hat nur zwei Varianten:
    int main()
    int main(int argc, char *argv[])

    - void main() ist somit unzulässig, auch wenn die meisten Compiler das zulassen.

    Zeile 23: clrscr() -> kein standard C 😉
    Zeile 24 ff: puts() bietet sich an, wenn du eh ein \n am Ende hast und nichts umwandeln musst.
    Zeile 32: getch() ist kein standard C.
    Zeile 35: Wie gesagt, mit Startparametern geht das alles einfacher, deswegen schreibe ich da jetzt nichts mehr zu.

    Zeile 58: Du könntest auch schreiben (char name[]) oder (char *name). Die Zahl bringt's nicht.
    Zeile 61: Du solltest scanf() sagen wie groß der Puffer ist, damit scanf() ihn nicht überschreibt. scanf("%29s", name); 29 wegen der Nullterminierung. Zudem lässt scanf() das '\n' im Puffer, was nervig sein kann. Mit fgets() könntest du z.B. auch einlesen, da musst du das '\n' dann aber aus dem String streichen. ( string[strlen(string) - 1] = '\0'; )
    http://www.cplusplus.com/reference/clibrary/
    Die Seite ist ganz praktisch, falls du sie noch nicht kennst.

    Zeile 72: Die Schleife ist irgendwie doppelt gemoppelt. Du prüfst die Abbruchbedingung innerhalb der Schleife manuell selbst. Überlege, wie man das vielleicht noch verbessern könnte.

    Jetzt hab ich keine Lust mehr, vielleicht schreibe ich später noch was 😃



  • Kannst du kurz beschreiben was in dem Header

    #include <eigene.h>
    

    drin ist?

    Ich mag keine Funktionsnamen mit Umlauten - aber das ist vielleicht Geschmackssache 😃

    MfG f.-th.



  • Auch ein paar Anmerkungen von mir

    1. Vergiss float, nimm double.
    float hatte mal Bedeutung, als Speicher knapp war. Heutzutage noch bei Berechnungen auf/in der Grafikkarte.

    2. Funktionen sollten einen Rückgabewert bekommen.
    Wie soll die übergeordnete Funktion denn wissen, dass die Datei bei lesen() nicht existiert?
    Du kannst auch bestehende Parameter zurückgeben.

    char* datei (char name [])
    {   // clrscr();
        printf ("\nBitte Namen der einzulesenden CSV-Datei eingeben: ");
        scanf ("%s",name); // %s geht nicht bei Dateinamen mit Leerzeichen
        return(name)
    }
    ...
         case '1': lesen (datei(name)); // lesen benutzt den Rücgabewert von datei()
                   break;
    ....
    

    3. Funktionen sollen das machen wofür sie da sind.
    lesen() soll eine Datei lesen und nicht mit dem User "reden". Den Fehler kann die übergeordnete Funktion abarbeiten. Du kannst die Funktion dann auch benutzen, falls du mal eine GUI baust oder mit Ein/Ausgabeumleitung arbeitest.
    lesen() gibt dann -1 zurück, wenn die Datei nicht geöffnet werden kann.

    ...
         case '1': if(lesen (datei(name))) < 0 {
                     printf("\nDie Datei kann nicht gelesen werden");
                     getch();
                   }
                   break;
    ....
    

    4. Vergiss float, nimm double.
    Gerade bei Messwerten.
    Aber wenn es um Geldbeträge geht nimmst du int (oder long oder long long)



  • Probleme sind behoben. danke für dir hilfe


Anmelden zum Antworten