Probleme beim Einlesen von Werten



  • Zeig doch mal bitte, wie du die Dateien schreibst.



  • Wir haben mal ein Programm geschrieben mit dem wir eine Datei erstellen und Inhalte einfügen können. Hier der Quellcode:

    #include <stdio.h>
    #include <eigene.h>
    #include <conio.h>
    
    //<dateizeiger>=fopen(<dateiname>,<modus>);
    
    void datei (char[]);
    void schreiben (char[]);
    void lesen (char[]);
    void groesse (char[]);
    
    void main (void)
    {	char name[30];
    	char wahl;
    	datei (name);
    
    	do
    {	clrscr();
    	printf("\t\tDateinamen eingeben..........1\n");
    	printf("\t\tWerte in Datei schreiben.....2\n");
    	printf("\t\tWerte aus Datei lesen........3\n");
    	printf("\t\tGroesse der Datei anzeigen...4\n\n");
    	printf("\t\tProgramm beenden...........X/x\n\n");
    	wahl=getch();
    
    switch (wahl)
    	{	case'1':datei (name);break;
    		case'2':schreiben (name);break;
    		case'3':lesen (name);break;
    		case'4':groesse (name);break;
    
    	}
    }while (wahl!='x'&&'X');
    }
    void datei (char name[30])
    { clrscr();
    	printf("\nBitte Name der Datei: ");
    	scanf ("%s",name);
    }
    
    void lesen (char name[30])
    { 
    	float wert;
    	FILE*datei;
    	datei=fopen(name,"r");
    	if (datei)
    	{
    	clrscr();
    	do
    	{	//fscanf(datei,"%f ",&wert);
    		fread(&wert,sizeof(float),1,datei);
    		if (!feof(datei))printf("%f\n",wert);
    	}while (!feof(datei));
    	fclose (datei);
    }else printf ("\Aus der gewünschten Datei kann nicht gelesen werden");
     getch();	
    }
    
    void schreiben (char name[30])
    
    {	float wert;
    	char ant;
    	FILE*datei;
    	datei=fopen(name,"w");
    	do
    	{
    	clrscr();
    	printf("Bitte eine reele Zahl: ");
    	scanf("%f",&wert);
    	//fprintf(datei,"%f ",wert);
    	fwrite(&wert,sizeof(float),1,datei);
    	printf("\nNoch eine Zahl ?");
    	ant=getch();
    	}while (ant=='j');
    
    	fclose (datei);
    
    }
    
    void groesse (char name[30])
    
    {	
    	FILE*datei;
    	int g;
    	datei=fopen(name,"r");
    	fseek(datei,0,SEEK_END);
    	g=ftell (datei);
    	g=g/sizeof(float);
    	printf("Es sind derzeit: %i Zahlen in der Datei.",g);
    	fclose(datei);
    	getch();
    
    }
    

    [code]

    Damit erzeuge ich dann beispielsweie eine Datei hallo.csv: Kopier die in den entsprechenden Ordner und ruf die in meinem Programm dann auf.



  • Zeile 50 gehört jetzt in das Projekt und Zeile 71 auch. Zeilen 51 und 72 gehören raus. Wir wollen ja auch mit fscanf wieder einlesen und nicht mehr mit fread.



  • Wenn du mit fprintf schreibst, stehen die Zahlen als Text in der Datei. Somit kannst du von der Größe der Datei nicht mehr darauf schließen, wie viele Zahlen jetzt drin stehen.

    <conio.h> und somit auch getch() etc. sind kein standard C.

    Was mir immer noch nicht so ganz klar ist, was soll das Programm überhaupt machen? Es schreibt Zahlen als Text in eine Datei, und liest diese auch wieder aus - aber letzten Endes machst du nichts damit 😕

    (Kommentare über die Einrückung etc. spare ich mir hier mal oO)



  • Ne das sind nur Teilprogramme. Wollte die Fehlermöglichkeiten möglichst klein halten. Das Programm soll auf Wunsch Standardabweichung, Schwankungsbreite und Trendgerade von Werten, aus einer Datei eingelesen, berechnen. Die Datei erstellen wir vorher mit einem anderen Programm.

    Hier ist mal mein aktueller Quellcode:
    Das Problem mit der Dateigröße hat sich auch geklärt.

    #include <stdio.h>		//normale Ein-/Ausgabe
    #include <math.h>		//wegen Wurzel und Quadrat
    #include <conio.h>		// wegen getch()
    #include <eigene.h>		// wegen clrscr()
    #include <string.h>		// wegen Dateiarbeit
    
    void datei(char[]);// unsere einzelnen Funktionen
    void lesen(char[]);	
    void Schwankungsbreite(char[]);
    void arithmetisches_Mittel(char[]);
    void Koeffizienten(char[]);
    void Vergleich_Trendgerade (char[]);
    
    int g;						// Dateigroesse
    double messwert[50];			// Feld für einzelne Messwerte
    
    void main (void)
    {	char name [30];
    	char wahl;
    	datei(name);				// gezwungener Aufruf der Funktion: datei
    	do
    	{
    	 clrscr(); // Bildschirm löschen und dann unser Menü anzeigen
    	 printf ("\t\n\nImportieren der Messwerte aus CSV-Datei.................................1\n");
    	 printf ("\t\n\nBerechnung und Ausgabe der Schwankungsbreite der Messwerte..............2\n");
    	 printf ("\t\n\nBerechnung und Ausgabe des arith. Mittels und der Standardabweichung....3\n");
    	 printf ("\t\n\nBerechnung und Ausgabe der Koeffizienten der Trendgeradenm..............4\n");
    	 printf ("\t\n\nVergleich der tatsaechlichen Messwerte mit der Trendgeraden.............5\n");
    	 printf ("\t\n\nProgrammende ...........................................................E\n");
    	 wahl=getch();
    
    	 switch (wahl)  // Menüauswahl treffen
    	 {
    		case '1':datei(name);break;				
    		case '2':Schwankungsbreite (name);break;
    		case '3':arithmetisches_Mittel (name); break;
    		case '4':Koeffizienten (name); break;
    		case '5':Vergleich_Trendgerade (name); break;
    		case 'E':printf("\nProgrammende\n\n");break;
    		default: printf ("Falsche Eingabe, bitte neu: ");
    		getch();
    	 }
      } while (wahl!='E');
    
    }	
    
    void datei (char name [30])
    {	
    	clrscr();
    	FILE*datei;
    	printf ("\nBitte Namen der einzulesenden CSV-Datei eingeben: ");
    	scanf ("%s",name);
    	datei=fopen(name,"r");
    
    	// Dateigröße ermitteln
    	struct {float a;short b;char c[];}satz;
    	fseek(datei,0,SEEK_END);
    	g=ftell (datei);
    	g=g/sizeof(satz);
    	printf("Dateigroesse: %i daten ",g);
    	// Messwerte einlesen
    	int i;						// Zählervariable
    
    	rewind (datei);				// Dateizegier wieder auf Anfang setzen
    	for (i=0;i<g;i++)
    	{	
    		//fread(&messwert[i],sizeof(float),1,datei);
    		fscanf(datei,"%lf ",&messwert[i]);
    		printf("\nDer %i. Wert betraegt: %lf",i+1,messwert[i]);//brauch man nicht nur zu Kontrolle
    
    	}fclose (datei);
    	getch();
    }// Ende Funktion: datei
    
    // Schwankungsbreite
    void Schwankungsbreite(char name [30])
    {	
    	clrscr();
    	float max,min,diff;
    	int i;
    
    	max=0;
    	for (i=0;i<g;i++)
    	{	
    		if
    		(messwert[i]>max)
    			max=messwert[i];
    		else ;
    	}printf("\nDer maximal Wert betraegt: %lf",max);
    
    	min=max;
    	for (i=0;i<g;i++)
    	{	
    		if
    		(messwert[i]<min)
    			min=messwert[i];
    		else ;
    	}printf("\nDer minimal Wert betraegt: %lf",min);
    		printf("\n\nDie Messwerte schwanken zwischen %lf und %lf.",min, max);
    
    		diff=max-min;
    		printf("\n\nDie Messwerte schwanken um %lf.",diff);
    
    	// Werte in Protokolldatei schreiben
    	{	FILE*fp;
    	fp=fopen ("Protokolldatei.txt","a");
    
    		fprintf (fp,"\nDer maximal Wert betraegt: %lf",max);
    		fprintf (fp,"\nDer minimal Wert betraegt: %lf",min);
    
    	fclose (fp);
    	}getch();
    }
    
    // arithmetisches Mittel und Standardabweichung
    void arithmetisches_Mittel(char name [50])
    {	
    	clrscr();
    	float ergebnis,summe;		// Hilfsvariablen: ergebnis=Arith. Mittel und Summe=Summe aller Messwerte
    	int i;						// Zählervariable
    
    	summe=0;
    	for (i=0;i<g;i++)
    	{	
    	summe+=messwert[i];
    	ergebnis=summe/g;
    	}	
    
    	printf ("\nDas arithmetische Mittel betraegt: %lf\n\n",ergebnis);
    
    	float v[50],z,s;	// v=x-/x; z= Zwischenergebnis nach dem Quadrieren; t= z/(n-1); s=standardabweichung
    	int j;				// Zählervariable
    
    	for (j=0;j<g;j++)
    	z=0;
    	for (i=0;i<g;i++)
    	{
    	v[j]=messwert[i]-ergebnis;		// berechnung von v für jeden einzelnen Messwert
    
    	z=z+pow((v[j]),2);
    	}
    	s=sqrt(z/(g-1));
    
    	printf("Die Standardabweichung betraegt: %lf\n\n",s);
    
    	getch();
    
    	// Werte in Protokolldatei schreiben
    	{	FILE*fp;
    	fp=fopen ("Protokolldatei.txt","a");
    
    		fprintf (fp,"\nDas arithmetische Mittel betraegt: %lf",ergebnis);
    		fprintf (fp,"\nDie Standardabweichung betraegt: %lf",s);
    
    	fclose (fp);
    	}
    }// Ende der Funktion: Arithmetisches Mittel
    
    // Koeffizienten der Trandgeraden
    void Koeffizienten(char name [30])
    {
    }
    
    // Vergleich der Koeffizienten der Trandgeraden
    void Vergleich_Trendgerade(char name [30])
    {
    }
    

    [code]



  • Globale Variablen sind böse 😉
    Wenn die Zahlen eh als Text vorliegen, braucht man kein Programm mehr um sie zu schreiben oder? Geht ja auch mit einem Texteditor. Von dem Menü würde ich auch Abschied nehmen, über Startparameter kann man das eigentlich einfacher regeln. (Ist auch üblicher).

    Einlesen kann man z.B. so machen:

    void read_file(const char *name, double *buf, int size) // Größe des Arrays übergeben, um Überlauf zu vermeiden. Wichtig!
    {
      FILE *file = fopen(name, "r");
      if (!file)
        perror(name), exit(-1);
      while (size-- && 1 == fscanf(file, "%lf ", buf++)) // scanf() gibt die Anzahl der erfolgreich gelesenen Einheiten zurück.
        printf("%lf\n", *(buf - 1)); // hier kannst du auch einfach ein ";" schreiben, das printf dient nur der Überprüfung.
    }
    
    int main(int argc, char *argv[])
    {
      double nums[50];
      if (argc < 2)
        return -1; // Hier würde man dann ausgeben, wie das Programm zu bedienen ist.
      read_file(argv[1], nums, sizeof(nums) / sizeof(*nums));
    }
    


  • Gut,also das mit der Dateigrösse auslesen klappt doch nicht. Es werden mehr Werte eingelesen als in der Datei sind und als 0 angegeben. Weist du warum?



  • eydasgehtab schrieb:

    Gut,also das mit der Dateigrösse auslesen klappt doch nicht. Es werden mehr Werte eingelesen als in der Datei sind und als 0 angegeben. Weist du warum?

    cooky451 schrieb:

    Wenn du mit fprintf schreibst, stehen die Zahlen als Text in der Datei. Somit kannst du von der Größe der Datei nicht mehr darauf schließen, wie viele Zahlen jetzt drin stehen.

    Lies bitte meinen Post oben, du musst die Dateigröße gar nicht auslesen!



  • eydasgehtab schrieb:

    Gut,also das mit der Dateigrösse auslesen klappt doch nicht. Es werden mehr Werte eingelesen als in der Datei sind und als 0 angegeben. Weist du warum?

    Wenn du eine Fließkommazahl mit %f bei printf ausgibst, werden üblicherweise 6 Nachkommstellen angegeben. Dann kommen noch die Vorkommastellen, der Dezimalpunkt und das Leerzeichen dazu. Macht ca. 10 bis 16 Zeichen.

    sizeof(float) ist auf den meisten Systemen 4.

    Mit printf werden die Variablen (meist) in ASCII-Zeichen geschrieben.
    Bei fwrite wird die Variable binär in die Datei geschrieben.



  • Hab jetzt von meinem Dateigröße Auslesen und der For- Schleife danach Abschied genommen. Mach es jetzt nur noch mit einer Do-while-Schleife. und lass dann auch jedes mal g inkrementieren. Funktioniert soweit auch.

    do
    {       i=i+1;
            g=g+1;
            fscanf(datei,"%lf ",&messwert[i]);
            printf("\nDer %i. Wert betraegt: %lf",i+1,messwert[i]);
    }while(!feof(datei));
    


  • Wo ist denn jetzt der Unterschied zwischen i und g ?
    Und warum machst du am Anfang schon i=i+1 ?



  • Hab das noch geändert, ich inkrementier i und g natürlich erst am Ende der Schleife. Der erste Index ist also 0 so wie i auch initialisiert wird. Der Unterschied zwischen i und g ist der, dass i einfach in jeder Funktion als Index des Feldes und als Zählervariable für for- Schleifen genommen wird und somit der Index immer stimmt. g ist global vereinbart und stellt die Anzahl der Messwerte da. Man hätte es bestimmt auch kombinieren können.Aber so funktionierts auch 😉


Anmelden zum Antworten