Datensatz aus Datei lesen, filtern und sortieren



  • #include <stdio.h>
    #include <string.h>
    
    typedef struct {
    		int Nummer;
    		char Zeit[100];
    		char Art[100];
    		double wert;
    
    	} Parameter;
    
    int cmp(const void *a,const void *b)
    {
      Parameter p1=*(Parameter*)a;
      Parameter p2=*(Parameter*)b;
      return p1.wert>p2.wert?-1: p1.wert<p2.wert;
    }
    
    int main()
    {
    	FILE*Lese;
    	FILE*Schreibe;
    	int c;
            Parameter x,*p=0;
    
    	Lese=fopen ("Messwert.txt","r");
    	Schreibe=fopen ("Datei2.txt","w");
    
    	if (Lese==NULL)
    	{
    		printf("Die Datei konnte nicht geoeffnet werden!\n");
    	}
    
    	if (Schreibe==NULL)
    	{
    		printf("Die Datei konnte nicht erzeugt werden!\n");
    	}
       rewind(Lese); c=0;
    	 while(!feof(Lese))
         if( 4==fscanf(Lese,"%d%s%s%lf",&x.Nummer,x.Zeit,x.Art,&x.wert) )
    	     if( !strcmp("TypB",x.Art))
    		   {
             p=realloc(p,++c*sizeof*p);
             p[c-1]=x;
           }
    
        qsort(p,c,sizeof*p,cmp);
    
        while(c--)
          fprintf(Schreibe,"%d %s %s %f \n",p[c].Nummer, p[c].Zeit, p[c].Art,p[c].wert);
    
        free(p);
    		fclose(Lese);
    		fclose(Schreibe);
    		return 0;
    }
    


  • Wutz schrieb:

    #include <stdio.h>
    #include <string.h>
    
    typedef struct {
    		int Nummer;
    		char Zeit[100];
    		char Art[100];
    		double wert;
    
    	} Parameter;
    
    int cmp(const void *a,const void *b)
    {
      Parameter p1=*(Parameter*)a;
      Parameter p2=*(Parameter*)b;
      return p1.wert>p2.wert?-1: p1.wert<p2.wert;
    }
    
    int main()
    {
    	FILE*Lese;
    	FILE*Schreibe;
    	int c;
            Parameter x,*p=0;
    
    	Lese=fopen ("Messwert.txt","r");
    	Schreibe=fopen ("Datei2.txt","w");
    
    	if (Lese==NULL)
    	{
    		printf("Die Datei konnte nicht geoeffnet werden!\n");
    	}
    
    	if (Schreibe==NULL)
    	{
    		printf("Die Datei konnte nicht erzeugt werden!\n");
    	}
       rewind(Lese); c=0;
    	 while(!feof(Lese))
         if( 4==fscanf(Lese,"%d%s%s%lf",&x.Nummer,x.Zeit,x.Art,&x.wert) )
    	     if( !strcmp("TypB",x.Art))
    		   {
             p=realloc(p,++c*sizeof*p);
             p[c-1]=x;
           }
        
        qsort(p,c,sizeof*p,cmp);
    
        while(c--)
          fprintf(Schreibe,"%d %s %s %f \n",p[c].Nummer, p[c].Zeit, p[c].Art,p[c].wert);
    
        free(p);
    		fclose(Lese);
    		fclose(Schreibe);
    		return 0;
    }
    

    danke fehlt noch der #include <stdlib.h> hab ich eingefügt, bekomme allerdings hier

    p=realloc(p,++c*sizeof*p);
    

    folgenden fehler:

    error C2440: '=' : cannot convert from 'void *' to 'Parameter *'

    Auch das mit dem "*" habe ich noch nicht so ganz verstanden, kann man das irgendwie umgehen, weil das hatten wir noch nicht in unserem Kurs, möchte da ungern zuviel neues einbinden.



  • Du programmierst C Code mit einem C++ Compiler, typischer Anfängerfehler.



  • Wutz schrieb:

    Du programmierst C Code mit einem C++ Compiler, typischer Anfängerfehler.

    Ja bin Anfänger, wäre trotzdem nett wenn du mir bei dem Problem helfen könntest 😉

    Wir müssen (leider?!) das Visual Studio C++ 2008 verwenden, deswegen muss das Programm auch dadrin geschrieben werden.

    Danke



  • Wenn ihr die dynamische Speicherverwaltung noch nicht hattet, dann verwende einfach einen Array fester Größe.



  • Im VStudio musst du für C die Dateiendung auf .c setzen (nicht .cpp!) oder in den Projekteigenschaften C/C++ erweitert... /TC statt /TP setzen.



  • Wutz schrieb:

    Im VStudio musst du für C die Dateiendung auf .c setzen (nicht .cpp!) oder in den Projekteigenschaften C/C++ erweitert... /TC statt /TP setzen.

    Danke für die Info, aber bis jetzt haben wir das noch nicht so gemacht, obs jetzt die feine Art und Weise ist weiß ich nicht. Auf jeden Fall soll das Programm erstmal als cpp gespeichert/compiliert werden.

    Bezüglich Arrays steh ich auch etwas auf dem Schlauch. Wie kann ich die Datei bzw. die Werte darin dann in ein Array schreiben und dann auch sortieren?

    Wiegesagt quick and dirty, also einfach und simpel der Code ohne großen schnick schnack.



  • Ich habe die bisherigen Code ein wenig gemixed und auf Array umgeschrieben. Dürfen nicht mehr als 100 Messwerte(Treffer vom gesuchten Typ) in der Datei sein... Aber ich vermute ihr hattet bislang keine Speicherverwaltung. Wutz Variante ist Aufgrund des dynamischen Arrays jedoch die Beste!

    #include <stdio.h> 
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct
    { 
    	int Nummer; 
    	char Zeit[100]; 
    	char Art[100]; 
    	double wert; 
    } Parameter; 
    
    int cmp(const void *a,const void *b) 
    { 
      Parameter p1=*(Parameter*)a; 
      Parameter p2=*(Parameter*)b; 
      return p1.wert>p2.wert?-1: p1.wert<p2.wert; 
    } 
    
    int main() 
    { 
    	const int parametersize = 100;
    
    	Parameter x, p[parametersize]; 
    
    	FILE* Lese=fopen ("Messwert.txt","r"); 
    	if (Lese==NULL) 
    	{ 
    		printf("Die Datei konnte nicht geoeffnet werden!\n");
    		return 1;
    	} 
    
        int c=0; 
    	rewind(Lese);
    	while(!feof(Lese)) 
    		if( 4==fscanf(Lese,"%d%s%s%lf",&x.Nummer,x.Zeit,x.Art,&x.wert) ) 
    			if( !strcmp("TypB",x.Art)) 
    				p[c++]=x; 
    
    	fclose(Lese); 
    
        qsort(p,c,sizeof*p,cmp); 
    
    	FILE* Schreibe=fopen ("Datei2.txt","w"); 
    	if (Schreibe==NULL) 
    	{ 
    		printf("Die Datei konnte nicht erzeugt werden!\n");
    		return 2;
    	} 
    
        while(c--) 
    		fprintf(Schreibe,"%d %s %s %f \n",p[c].Nummer, p[c].Zeit, p[c].Art,p[c].wert); 
    
        fclose(Schreibe); 
    
        return 0; 
    }
    


  • HighLigerBiMBam schrieb:

    Wutz Variante ist Aufgrund des dynamischen Arrays jedoch die Beste!

    wenn er auch noch rückgabewerte testen würde...



  • danke @HighLigerBiMBam

    könntest du mir noch kurz erklären was es mit den ganzen "*" auf sich hat und ob es vielleicht auch ohne geht?

    und wie könnte man das ganze mit bubblesort realisieren?



  • Die "*" sind Zeiger, nachlesen ist wichtig zu wissen. wenn du bubblesort verwenden willst, dann musst du dies nur anstelle des qsort verwenden. Die cmp-Funktion brauchst du dann natürlich auch nichtmehr.



  • hallo.

    wie kann ich es ändern, dass das programm vom Größten zum kleinen Wert ordnet?

    Bis jetzt ist es ja vom kleinsten zum größten, wir sollen das allerdings anders rum machen.

    gibts ferner noch weitere hinweise wie ich den code von "HighLigerBiMBam" noch weiter vereinfachen kann. denn da sind sehr viele sachen drin die wir noch nicht hatten vorallem das mit den "*" aber auch so sachen wie

    p1.wert>p2.wert?-1
    

    mit dem "?"

    ansonsten wäre es nett, wenn du oder jemand anders den code mal kommentieren könnte (am besten für vollblut anfänger)

    HighLigerBiMBam schrieb:

    Ich habe die bisherigen Code ein wenig gemixed und auf Array umgeschrieben. Dürfen nicht mehr als 100 Messwerte(Treffer vom gesuchten Typ) in der Datei sein... Aber ich vermute ihr hattet bislang keine Speicherverwaltung. Wutz Variante ist Aufgrund des dynamischen Arrays jedoch die Beste!

    #include <stdio.h> 
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct
    { 
    	int Nummer; 
    	char Zeit[100]; 
    	char Art[100]; 
    	double wert; 
    } Parameter; 
    
    int cmp(const void *a,const void *b) 
    { 
      Parameter p1=*(Parameter*)a; 
      Parameter p2=*(Parameter*)b; 
      return p1.wert>p2.wert?-1: p1.wert<p2.wert; 
    } 
    
    int main() 
    { 
    	const int parametersize = 100;
     
    	Parameter x, p[parametersize]; 
    
    	FILE* Lese=fopen ("Messwert.txt","r"); 
    	if (Lese==NULL) 
    	{ 
    		printf("Die Datei konnte nicht geoeffnet werden!\n");
    		return 1;
    	} 
    
        int c=0; 
    	rewind(Lese);
    	while(!feof(Lese)) 
    		if( 4==fscanf(Lese,"%d%s%s%lf",&x.Nummer,x.Zeit,x.Art,&x.wert) ) 
    			if( !strcmp("TypB",x.Art)) 
    				p[c++]=x; 
    
    	fclose(Lese); 
        
        qsort(p,c,sizeof*p,cmp); 
    
    	FILE* Schreibe=fopen ("Datei2.txt","w"); 
    	if (Schreibe==NULL) 
    	{ 
    		printf("Die Datei konnte nicht erzeugt werden!\n");
    		return 2;
    	} 
    
        while(c--) 
    		fprintf(Schreibe,"%d %s %s %f \n",p[c].Nummer, p[c].Zeit, p[c].Art,p[c].wert); 
        
        fclose(Schreibe); 
    
        return 0; 
    }
    


  • ich push das hier nochmal, und hoffe dass mir noch jemand weiter helfen kann bezüglich vereinfachung des quellcodes und richtiger sortierung



  • habs nun mal mit bubblesort probiert, aber ich bekomme immer einen fehler:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct
    {
        int Nummer;
        char Zeit[100];
        char Art[50];
        double wert;
    } Parameter;
    
    void bubbleSort(double numbers[], int array_size)
    {
      int i, j;
      double temp;
    
      for (i = (array_size - 1); i >= 0; i--)
      {
        for (j = 1; j <= i; j++)
        {
          if (numbers[j-1] > numbers[j])
          {
            temp = numbers[j-1];
            numbers[j-1] = numbers[j];
            numbers[j] = temp;
          }
        }
      }
    }
    
    int main()
    {
        const int parametersize = 100;
    
        Parameter x, p[parametersize];
    
        FILE* Lese=fopen ("Messwert.txt","r");
        if (Lese==NULL)
        {
            printf("Die Datei konnte nicht geoeffnet werden!\n");
            return 1;
        }
    
        int c=0;
        rewind(Lese);
    
        while(!feof(Lese))
            if( 4==fscanf(Lese,"%d%s%s%lf",&x.Nummer,x.Zeit,x.Art,&x.wert) )
                if( !strcmp("Art2",x.Art))
                    p[c++]=x;
    
        fclose(Lese);
    
      bubbleSort(p,c);
    
        FILE* Schreibe=fopen ("Datei2.txt","w");
        if (Schreibe==NULL)
        {
            printf("Die Datei konnte nicht erzeugt werden!\n");
            return 2;
        }
    
        while(c--)
            fprintf(Schreibe,"%d %s %s %f \n",p[c].Nummer, p[c].Zeit, p[c].Art,p[c].wert);
    
        fclose(Schreibe);
    
        return 0;
    }
    

    56)bubbleSort' : cannot convert parameter 1 from 'Parameter [100]' to 'double []'



  • Parameter ist auch eine struct.

    Bei qsort gibt die cmp- Funktion zurück:

    -1 wenn p1 > p2
     0 wenn p1 == p2
    +1 wenn p1 < p2
    

    Überleg dir mal wie du cmp anpassen kannst.

    Das was HighLigerBiMBam benutzt hat ist der ? : (Fragenzeichen-Doppelpunkt) Operator.

    Wenn die Bedingung vor dem ? wahr ist (ungleich 0) nimm den Wert vor dem :
    sonst den dahinter. Das ist hier eine Bedingung die 0 (falsch) oder 1 (wahr) ist.

    Allerdings ist in C alles ungleich 0 wahr. Es muss nicht immer 1 sein.



  • also kann ich bubblesort nicht verwenden weil parameter eine struct ist?

    möchte gerne auf qsort verzichtne uns es mit bubblesort machen, da brauch ich die cmp funktion ja eh nicht.

    wie kann ich das machen, also wie kann ich den fehler beseitigen?

    danke



  • Ich habe es mir nicht angeschaut aber du darfst nicht die struct vergleichen, sondern den Wert!

    if (numbers[j-1] > numbers[j])
    

    sieht auf Anhieb falsch aus. Sollte das nicht so lauten?

    if (numbers[j-1].Wert > numbers[j].Wert)
    

    Edit: Ok hab mir dein Problem genauer angeschaut, die Funktion stimmt nicht. Du versuchst eine struct zu übergeben, aber die Funktion will ein double, du musst die Funktion komplett umshreiben, damit sie mit deinem Strukt funktioniert: In etwa so:

    void bubblesort(Parameter arr[], int length)
     {
         int i, j;
         for (i = 0; i < length; ++i) {
     	for (j = 0; j < length - i - 1; ++j) {
     	    if (array[j].wert > array[j + 1].wert) {
     		Parameter tmp = array[j];
     		array[j] = array[j + 1];
     		array[j + 1] = tmp;
     	    }
     	}
         }
     }
    

Anmelden zum Antworten