Aufgabe zum Montag bitte Hilfe



  • Aufgabe 3.5. CAN

    Bei der Aufgabe handelt es sich um die Vorbereitung der Nutzdaten CAN-Botschaft Bremse_3 für die grafische Darstellung, beispielweise für ein Bild mit 1000 x 1000 Punkten.

    Schritt 1. Lesen Sie jetzt die Daten aus der vollständigen Datei CanDaten.dat und ermitteln Sie die Anzahl der Zeilen mit Daten. Die Angabe brauchen Sie für die Dimensionierung eines Arrays für die Aufgabe.
    Hinweise:
    1.Definieren Sie eine zusätzliche Variable vom Typ float, die die eingelesenen Werte übernimmt und immer wieder überschrieben werden soll. Sie spielt lediglich die Rolle der Platzhalter, bei dem Schritt interessieren wir uns für die Inhalte der eingelesenen Daten noch nicht.
    2. Definieren Sie eine Variable vom Typ long für den Zeilen-Zähler, wir wissen noch nicht, wie viele Zeilen in der Datei gespeichert sind. Sehen Sie vor, dass wenn Sie mit der do{}while() Schleife die Daten einlesen, wird den Zähler n+1 mal hochgezählt, bevor die Bedingungen für die Schleife nicht mehr erfüllt sind.

    Schritt 2. Definieren Sie im Hauptprogramm ein zweidimensionales float-Array daten[Anzahl_der_Zeilen][5] für die Bearbeitung der Nutzdaten CAN-Botschaft Bremse_3 aus der vollständigen Datei CanDaten.dat. Der Name der ersten Dimension [Anzahl_der_Zeilen] ist selbsterklärend, die zweite Dimension [5] ist für die Zeit und die Geschwindigkeit der vier einzelnen Räder. Initialisieren Sie das Array mit Daten aus der Datei CanDaten.dat und schließen Sie die Datei.
    Hinweis:
    Der Lesezeiger steht jetzt am Ende der Datei, mit der Standard-Funktion fseek() kann er wieder am Anfang der Datei positioniert werden:fseek(fp,0,SEEK_SET);

    Schritt 3. Für die Berechnung des Skalierungsfaktors für die x- oder y-Achse werden die Angaben für jeweiligen minimalen und maximalen Werte sowie die Größe des Bildes notwendig. Der minimale und der maximale Wert für die x-Achse entsprechen der ersten und der letzten Angabe für die Zeit. Definieren Sie zwei Variablen für die Angaben zur Größe des Bildes, initialisieren Sie diese jeweils mit 1000 und berechnen Sie den Skalierungsfaktor für die Zeit-Achse.

    Schritt 4. In einer geschachtelten for-Schleife für alle Geschwindigkeiten aller Räder ermitteln Sie die minimalen und die maximalen Angaben für die y-Achse und berechnen Sie den Skalierungsfaktor für die Geschwindigkeit.

    Schritt 5. Die Werte für die Geschwindigkeit liegen im Bereich von ca. 40 bis 70. Für die optimale Darstellung der Kurven in einem Bild möchten wir den minimalen Wert so verlegen, dass er nah zu dem Null-Punkt des Bildes liegt. Passen Sie die Daten entsprechend an: ziehen Sie den minimalen Wert des Arrays von allen y-Werten ab.

    Schritt 6. Skalieren Sie jetzt die Daten und speichern Sie diese in der Datei CanDatenSkaliert.dat auch wie die eingelesene Daten mit 5 Zahlen in einer Zeile, jetzt aber als int-Werte, für die Darstellung in einem Bild sind ganzzahlige Werte notwendig.

    Hinweis: Die explizite Typumwandlung vom Typ float zu int wird mit dem Ausdruck (int) variablename durchgeführt, z.B.
    int Daten[i][0];

    Schritt 7. Testen Sie Ihr Programm mit anderen Angaben für das Bild: z.B. mit der Höhe 400 und der Breite 800 Pixel. Öffnen Sie die Datei CanDatenSkaliert.dat und prüfen Sie, ob es in der Spalte für die Zeit keine Angabe über 800 und in den Spalten für die Geschwindigkeit keine Angaben über 400 gibt.

    CanDaten.dat
    http://www.4shared.com/file/Hrldt4bW/CanDaten.html

    Das war die Aufgabe. Ich habe viel probiert aber leider Erfolglos 👎

    /* 
     * File:   Aufgabe3.5.c
     * Author: Metro
     *
     * Created on 4. Mai 2012, 22:59
     */
    
    #include <stdio.h>
    #include <io.h> 
    #include <stdlib.h>
    
    /*
     * 
     */
    
    int main(void) {
        int long lines;
        int i,j;
        float z;
        char* zeile ;
    
        FILE* fp = fopen("Candaten.dat", "r");
        if (fp == NULL)
        {
            printf("Datei kann nicht geoeffnet werden\n");//fehler meldung
        }
        else
        {
            char* zeile ;        
            for (lines=0;fgets(zeile,100,fp);++lines){}
        }
      float t;
      fseek(fp,0,SEEK_SET);
    
      float Daten[lines][5];
      int zeiger=2;
      for(i=0;i<lines;i++)
          for(j=0;j<5;j++)
          {
              fseek(fp,zeiger,SEEK_SET);
              fscanf(fp, "%f", &t);
              Daten[i][j]=t;
              zeiger+=11;
          }
      fclose(fp);
    
        return (0);
    }
    


  • Versuche es mal damit.!!

    1. Variablen immer am anfang definieren und initialisieren!!
    2. fgets <- ist ein char[] und nicht char* !!
    3. UND WICHTIGSTES!!! Hausaufgaben selber machen !!!😡 😮 😡
    int main(void) { 
    
      int long lines=1;
      float Daten[lines][5]; 
      int zeiger=2; 
      float t; 
        int i,j;
        char zeile[100];
    
        FILE* fp = fopen("can.txt", "r"); 
        if (fp == NULL) 
        { 
            printf("Datei kann nicht geoeffnet werden\n");//fehler meldung 
        } 
        else 
        { 
            for (lines=0; fgets(zeile,100,fp); ++lines)
    			{
    				printf("%d> %s",lines ,zeile);
    			}
    		printf("\n\n Es sind %d Lines\n",lines);
        } 
      fseek(fp,0,SEEK_SET); 
    
      for(i=0;i<lines;i++) 
          for(j=0;j<5;j++) 
          { 
              fseek(fp,zeiger,SEEK_SET); 
              fscanf(fp, "%f", &t); 
              Daten[i][j]=t; 
              zeiger+=11; 
          } 
      fclose(fp); 
    
        return (0); 
    }
    

    PS.: Es wahren 3 Fehler 😃 Durchgefallen 😉



  • wesam88 schrieb:

    Das war die Aufgabe. Ich habe viel probiert aber leider Erfolglos 👎

    Das ist eine der schlechtesten Fehlerbeschreibungen die du machen kannst.
    Man weiß gar nicht wo man dir helfen soll.

    coolzero0001 schrieb:

    Versuche es mal damit.!!

    1. Variablen immer am anfang definieren und initialisieren!!
    2. fgets <- ist ein char[] und nicht char* !!
      ...
    int long lines=1;
      float Daten[lines][5];
    

    1. muss man das seit C99 nicht mehr machen und du nutzt mit den VLA (Zeile 4) selber C99 Features.
    2. interessiert das fgets nicht, denn es kann den Unterschied nicht fesstellen.
    Wichtig ist, das fgets einen gültigen Speicher zum beschreiben bekommt.
    Ob das ein Array oder dynamischer Speicher ist, ist egal.



  • totalen Schrott.



  • wesam88 schrieb:

    Aufgabe zum Montag bitte Hilfe /* <- tolles Timing, viele kommen hier erst So. >22Uhr mit ihren Fragen zu Montag */

    http://www.4shared.com/file/Hrldt4bW/CanDaten.html
    /* <- war jetzt nicht wirklich ernst gemeint, da man sich zur Dateneinsicht erst registrieren muss */

    /* 
     * File:   Aufgabe3.5.c
     * Author: Metro
     *
     * Created on 4. Mai 2012, 22:59
     */
    
    #include <stdio.h>
    #include <io.h> /* <- Müll, raus damit */
    #include <stdlib.h>
    
    /*
     * 
     */
     
    int main(void) {
        int long lines; /* <- Müll, raus mit int */
        int i,j;
        float z;
        char* zeile ;
        
        FILE* fp = fopen("Candaten.dat", "r");
        if (fp == NULL)
        {
            printf("Datei kann nicht geoeffnet werden\n");/* <- Müll, hier muss Programmende mit return oder exit() hin */
        }
        else
        {
            char* zeile ;  /* <- falsch, hier wird kein Speicherbereich definiert, außerdem ist zeile schon zuvor definiert */      
            for (lines=0;fgets(zeile,100,fp);++lines){} /* falsches Ergebnis, wenn Zeilen >99 Zeichen vorliegen */
        }
      float t;
      fseek(fp,0,SEEK_SET); /* <- Professorenschrott, muss portabel natürlich fseek(fp,0L,SEEK_SET) heißen, besser einfach rewind(fp) */
      
      float Daten[lines][5]; /* oberhässliches VLA, auch Professorenmüll */
      int zeiger=2; /* <- ein Zeiger ist kein int, ein int ist kein Zeiger */
      for(i=0;i<lines;i++)
          for(j=0;j<5;j++)
          {
              fseek(fp,zeiger,SEEK_SET); /* <- Müll, raus damit */
              fscanf(fp, "%f", &t); /* <- fscanf positioniert fp schon für dich, explizites o.g. fseek macht nur alles wieder kaputt */
              /* hier fscanf-Rückgabewert unbedingt auswerten, damit bemerkst du evtl. falsch einlesene Daten */
              Daten[i][j]=t;
              zeiger+=11;
          }
      fclose(fp);
       
      
        return (0);
    }
    

  • Mod

    Wutz schrieb:

    fseek(fp,0,SEEK_SET); /* <- Professorenschrott, muss portabel natürlich fseek(fp,0L,SEEK_SET) heißen, besser einfach rewind(fp) */
    

    Na, die korrekte implizite Umwandlung von 0 nach 0L ist dir aber schon portabel garantiert.



  • "...die korrekte implizite Umwandlung..." braucht z.B. nicht zu funktionieren bei einer Implementierung von fseek als Makro.
    Auf irgendwas Implizites zu vertrauen wenn man auch gleich was Eindeutiges explizit vorgeben kann ist auch nur Fehlerverschleierung und/oder bringt Portabilitätseinbußen mit sich, gerade für Lernende ungeeignet und aus Sicht von Lehrenden sogar schon fahrlässig.



  • fseek ist kein Makro, sonder eine Funktion (per Standard). Deine Argumentation ist albern. Sie wäre selbst dann albern, wenn fseek ein Makro sein dürfte, weil sich dieses Makro wie eine Funktion der Signatur int fseek(FILE*, long, int); verhalten müsste und bei deren Aufruf eine implizite Umwandlung stattfände. Ferner wird genau diese Umwandlung in einer Fußnote im Standard verwendet.



  • Versuche, die Aufgaben ein einzelne Funktionen zu separieren und von rein "technischen" Aktionen wie Dateioperationen zu trennen; in den Funktionen kannst du dich dann auf deine eigenen (fachlichen) Probleme konzentrieren:

    void skaliereZeit(float fm[][5],int i)
    {
      float minzeit=fm[0][0]; /* erster Wert einer Zeile soll wohl die Zeit sein ...; => Zeitwert des 1. Datensatzes/Zeile */
      float maxzeit=fm[i-1][0]; /* Arrays ist C beginnen immer bei 0 (und enden bei Größe-1); => Zeitwert des letzten Datensatzes/Zeile */
      float bereich=(maxzeit-minzeit);
      int x;
      for(x=0;x<i;++x)
        ...
    }
    
    void skaliereGeschwindigkeiten(float fm[][5],int i)
    {
    }
    
    void normiereGeschwindigkeiten(float fm[][5],int i)
    {
    }
    
    void ausgabeIntegerMatrix(float fm[][5],int i,char *name)
    {
      FILE *f=fopen(name,"w");
      int x,y;
      for(x=0;x<i;++x,fputc('\n',f)) /* hier die "Matrix"werte einzeln durchlaufen und als int-Wert in neue Datei schreiben */
        for(y=0;y<5;++y)
          fprintf(f,"%d ",(int)fm[x][y]);
      fclose(f);
    }
    
    int main(void) {
      FILE *f;
      if( f=fopen("Candaten.dat","r") )
      {
        int i=0;
        float *zeiger=0;
        while( (zeiger=realloc(zeiger,++i*sizeof*zeiger))!=0 && 1==fscanf(f,"%f",&zeiger[i-1]) ); /* alle durch Whitespaces getrennte float-Werte einlesen */
        fclose(f);
        --i;  /* i sind jetzt Anzahl der einlesenen float-Werte */
        i/=5; /* i ist jetzt Anzahl der Zeilen */
        skaliereZeit(zeiger,i);
        skaliereGeschwindigkeiten(zeiger,i);
        normiereGeschwindigkeiten(zeiger,i);
        ausgabeIntegerMatrix(zeiger,i,"CanDatenSkaliert.dat");
        free(zeiger);
      }
    
     return 0;
     }
    


  • @Wutz
    der totale schrott hat aber funktioniert 😮


  • Mod

    coolzero0001 schrieb:

    @Wutz
    der totale schrott hat aber funktioniert 😮

    Das hat der Kapitän der Titanik auch gedacht, als sie aus dem Hafen fuhr.



  • SeppJ schrieb:

    Wutz schrieb:

    fseek(fp,0,SEEK_SET); /* <- Professorenschrott, muss portabel natürlich fseek(fp,0L,SEEK_SET) heißen, besser einfach rewind(fp) */
    

    Na, die korrekte implizite Umwandlung von 0 nach 0L ist dir aber schon portabel garantiert.

    wutz ich bedanke mich bei dir
    Deine Hinweise helfen mir
    Ich habe meine Zeit verloren, mit fseek(fp,0,SEEK_SET)
    Ein Buchstabe spielt manschmal wichtige Rolle



  • Wutz schrieb:

    Versuche, die Aufgaben ein einzelne Funktionen zu separieren und von rein "technischen" Aktionen wie Dateioperationen zu trennen; in den Funktionen kannst du dich dann auf deine eigenen (fachlichen) Probleme konzentrieren:

    void skaliereZeit(float fm[][5],int i)
    {
      float minzeit=fm[0][0]; /* erster Wert einer Zeile soll wohl die Zeit sein ...; => Zeitwert des 1. Datensatzes/Zeile */
      float maxzeit=fm[i-1][0]; /* Arrays ist C beginnen immer bei 0 (und enden bei Größe-1); => Zeitwert des letzten Datensatzes/Zeile */
      float bereich=(maxzeit-minzeit);
      int x;
      for(x=0;x<i;++x)
        ...
    }
    
    void skaliereGeschwindigkeiten(float fm[][5],int i)
    {
    }
    
    void normiereGeschwindigkeiten(float fm[][5],int i)
    {
    }
    
    void ausgabeIntegerMatrix(float fm[][5],int i,char *name)
    {
      FILE *f=fopen(name,"w");
      int x,y;
      for(x=0;x<i;++x,fputc('\n',f)) /* hier die "Matrix"werte einzeln durchlaufen und als int-Wert in neue Datei schreiben */
        for(y=0;y<5;++y)
          fprintf(f,"%d ",(int)fm[x][y]);
      fclose(f);
    }
    
    int main(void) {
      FILE *f;
      if( f=fopen("Candaten.dat","r") )
      {
        int i=0;
        float *zeiger=0;
        while( (zeiger=realloc(zeiger,++i*sizeof*zeiger))!=0 && 1==fscanf(f,"%f",&zeiger[i-1]) ); /* alle durch Whitespaces getrennte float-Werte einlesen */
        fclose(f);
        --i;  /* i sind jetzt Anzahl der einlesenen float-Werte */
        i/=5; /* i ist jetzt Anzahl der Zeilen */
        skaliereZeit(zeiger,i);
        skaliereGeschwindigkeiten(zeiger,i);
        normiereGeschwindigkeiten(zeiger,i);
        ausgabeIntegerMatrix(zeiger,i,"CanDatenSkaliert.dat");
        free(zeiger);
      }
    
     return 0;
     }
    

    Ich finde so besser und gut aussieht, aber ich darf in dieser Aufgabe nur in HauptProgramm Arbeiten

    Aufjedenfall danke ich dir 🙂 🙂 🙂



  • #include <stdio.h> 
    #include <stdlib.h>
    
    /*
     * 
     */
    
    int main(void) {
        long lines;
        int i,k,j;
        float t,Zeit_min,Zeit_max,Rad_min,Rad_max,Rad_differenz;
        float Zeit_Skalierungsfaktor,Rad_Skalierungsfaktor;
        char* zeile ;
    
        FILE* fp = fopen("Candaten.dat", "r");
        if (fp == NULL)
        {
            printf("Daten kann nicht  geoeffnet werden\n");//fehler meldung
            return(0);
        }
        else
        {        
            for (lines=0;fgets(zeile,500,fp);++lines){}
        }
        fseek(fp,0l,SEEK_SET);
        float Daten[lines][5];
        float Datenskaliert[lines][5];
        for(i=0;i<lines;i++)
            for(j=0;j<5;j++)
            {
                fscanf(fp, "%f", &t);
                Daten[i][j]=t;
                Datenskaliert[i][j]=t;
    
            }
    
        Zeit_min=Daten[0][0];
        Zeit_max=Daten[lines-1][0];
        Zeit_Skalierungsfaktor=800/Zeit_max;
    
        Rad_max=Daten[0][1];
        Rad_min=Daten[0][1];
        float a[2];
        for(i=0;i<lines;i++)
            for(j=1;j<5;j++)
             {
               if (Daten[i][j] < Rad_min)
                    a[0] = Daten[i][j];
                if (Daten[i][j] > Rad_max)
                    a[1] = Daten[i][j];                
             }
        Rad_min=a[0];
        Rad_max=a[1];
       printf("%f\n%f\n",Rad_min,Rad_max);
    
        Rad_differenz= Rad_max- Rad_min;
    
        for(i=0;i<lines;i++) 
            Datenskaliert [i][0] *= Zeit_Skalierungsfaktor;
        Rad_Skalierungsfaktor = 400 / Rad_max;
        for(i=0;i<(lines);i++)
        {
            for(j=1;j<5;j++)
            {
                Datenskaliert[i][j] = (Datenskaliert[i][j] * Rad_Skalierungsfaktor);
            }
        }
            FILE *fp2;
        fp2=fopen("CanDatenSkaliert.dat","wt");
    
    //Fehlerabfrage
        if (fp2 == NULL)
        {
            printf("CanDatenSkaliert.dat kann nicht geoeffnet werden\n");
            return(-1);
        }
        for(i=0;i<lines;i++)
        {
            for(j=0;j<5;j++)
            {
                fprintf(fp2,"%2.0f\t ",Datenskaliert[i][j]);
                if (j % 5 == 4)
                    fprintf(fp2,"\n");
            }
        }
        fclose(fp2);
        fclose(fp);
    
        return (0);
    }
    

    Das habe ich gemacht, und das funktioniert 😉 😉


  • Mod

    SeppJ schrieb:

    coolzero0001 schrieb:

    @Wutz
    der totale schrott hat aber funktioniert 😮

    Das hat der Kapitän der Titanik auch gedacht, als sie aus dem Hafen fuhr.

    wesam88 schrieb:

    [...viel Code...]
    Das habe ich gemacht, und das funktioniert 😉 😉

    Der Eisberg sagt dazu:

    test.c: In function ‘main’:
    test.c:11:47: warning: variable ‘Rad_differenz’ set but not used [-Wunused-but-set-variable]
         float t,Zeit_min,Zeit_max,Rad_min,Rad_max,Rad_differenz;
                                                   ^
    test.c:11:13: warning: variable ‘Zeit_min’ set but not used [-Wunused-but-set-variable]
         float t,Zeit_min,Zeit_max,Rad_min,Rad_max,Rad_differenz;
                 ^
    test.c:10:11: warning: unused variable ‘k’ [-Wunused-variable]
         int i,k,j;
               ^
    [b]test.c:23:27: warning: ‘zeile’ may be used uninitialized in this function [-Wuninitialized]
             for (lines=0;fgets(zeile,500,fp);++lines){}[/b]
    

    ⚠ Der fett markierte ist schwerwiegend! ⚠



  • auch wenn einige sagen es ist alles schrott von mir!

    " Variablen immer am anfang definieren und initialisieren! "

    so wirds auch in der Technikerschule gelehrt.


Anmelden zum Antworten