Erklärung gesucht wtf macht der pointer da?



  • //      while(feof(fp)==0 )                                
                    {                                               
                            fgets(rdy,100,fp);                      
                            rpoint=strstr(rdy," R ");                  
                            cnt_ges++;
    
                   //       if(rpoint!=NULL)                                  
                            {
                                    getpids(rdy,string);
                                    l=atoi(string);
                                    printf("%d\n",l);
                                    getname(rdy,string);
                                    printf("%s\n",string);
                                    l=getcpu(rdy,string);
                                    printf("%d\n",l);
                                    printf("|%s|\n",string);
                                    printf("%d\n",zeitum("21:20:48"));
                                    cnt_run++;
                            }
                            l++;                                    
                            rpoint=NULL;                         
                    }
            }
    

    Die aufgerufenen Methoden:

    void getpids(char *fpoint,char *point) //soll 6 zeichen einlesen
    {
            int i=0;
            for(i=0;i<6;i++)
            {
                    *point=*fpoint;
                    point++;
                    fpoint++;
            }
    }
    //---------------------------------------------------------------------------
    void getname(char *fpoint,char *point) //soll 8 zeichen einlesen
    {
            int i=0;
            fpoint+=16;
            point-=6;
    
            for(i=0;i<14;i++)
            {
                    *point=*fpoint;
                    point++;
                    fpoint++;
            }
    }
    //--------------------------------------------------------------------------
    int getcpu(char *fpoint,char *point) //soll 8 zeichen einlesen
    {
            int i=0;
            fpoint+=49;
            point-=8;
            for(i=0;i<16;i++)
            {
                    *point=*fpoint;
                    point++;
                    fpoint++;
            }
            return(zeitum(point));
    }
    

    Die eingelesene Zeile:

    800539.pbs            atlas003 lhcbXL     1     1    --  21:20:48 51:07:00 Q c01-023-101
    

    Die Ausgabe:

    800539 //PID
    atlas003 //name
    0
    |21:20:48|//CPU-zeit die pipes sind nur da um zu sehen ob noch mehr eingelesen wurd
    76848
    

    Was ich nun nicht verstehe, beim Aufruf von getpid() ist der fpointer noch am Anfang der Zeile is klar. Aber beim Aufruf von getname() müßte er ja schon weiter sein, da er nicht zurückgesetzt wird. Trotzdem muss ich das Offset vom Zeilenanfang aus nehmen.
    Was noch verwirrender ist warum muss die Schleife immer länger laufen und wieso kann zeitum() das nicht umrechnen obwohl das Format stimmt?!?
    (die funktion zeitum(char* string) funktioniert richtig habs zur Kontrolle extra nochma direkt mit dem Wert aufgerufen)
    Ich hoffe jemand nimmt sich die Zeit und probiert da durchzusteigen.
    Gruß HiFish



  • Der übergebene Pointer ist eine KOPIE des Wertes, d.h. du änderst nicht den Wert im aufrufenden Programm, sondern nur lokal innerhalb deiner Funktion(en). Übrigens frage ich mich, wozu das "point-=xxx;" jeweils da ist - damit schreibst du effektiv in fremde Daten.



  • Ich hab gelesen das ich damit die Adresse auf die der Pointer zeigt ändere
    (http://www.pronix.de/pronix-740.html)
    was ja auch funktioniert ich krieg ja die richtigen Werte.

    Ok das mti dem Offset hab ich jetzt kapiert aber warum muss die Schleife immer länger laufen ? um 8 Zeichen einzulesen laeuft sie mal 14 mal 16 Runden (hab ich durch testen rausgefunden)
    Gruß HiFish



  • Ja, damit änderst du die Zieladresse, aber nur lokal - und da der Zeiger "string" im Hauptprogramm immer noch auf den Start deiner Zeichenfolge zeigt, landest du in fremden Speicherbereichen (da brauchst du sehr viel Glück, um keine wichtigen Daten zu zerstören).

    um 8 Zeichen einzulesen laeuft sie mal 14 mal 16 Runden (hab ich durch testen rausgefunden)

    Die Schleifen wurden auf 14 bzw. 16 Runden eingestellt 😉 Das Problem ist, daß du durch dein "point-=xxx;" vor dem Speicherbereich landest, aus dem du später lesen willst.

    Mal die Situation in der getname():

    * * * * * * 8 0 0 5 3 9 \0 ....
    ^           ^
    point       string
    v           v
                a t l a s 0 0 3 \0
    

    Du schreibst deine Daten in den Bereich ab 'point' und liest später ab 'string' wieder aus.



  • So hab den code jetzt abgeändert und krieg die Richtigen Werte 🙂 , jetzt ist nur noch die Frage warum zeitum 0 zurückliefert, steht da doch noch mehr in dem pointer?
    (Zeitum erwartet einen String im Format "xx:xx:xx")

    Ausgabe:

    800539
    atlas003
    0
    |21:20:48|
    76848
    

    Neuer Code:

    void getpids(char *fpoint,char *point)
    {
            int i=0;
            for(i=0;i<6;i++)
            {
                    *point=*fpoint;
                    point++;
                    fpoint++;
            }
    }
    //---------------------------------------------------------------------------
    void getname(char *fpoint,char *point)
    {
            int i=0;
            fpoint+=22;
    
            for(i=0;i<8;i++)
            {
                    *point=*fpoint;
                    point++;
                    fpoint++;
            }
    }
    //--------------------------------------------------------------------------
    int getcpu(char *fpoint,char *point)
    {
            int i=0;
            fpoint+=57;
            for(i=0;i<8;i++)
            {
                    *point=*fpoint;
                    point++;
                    fpoint++;
            }
            return(zeitum(point));
    }
    


  • Zeig doch mal die Funktion 'Zeitum()'.



  • Die hab ich realtiv am Anfang des Programms geschrieben bin grad dabei ne neue zu schreiben die ohne Datei anlegen auskommt.
    Gruß HiFish

    int zeitums(char* time)                 //Funktion um Zeit umzurechnen
    {                                       //von XX:XX:XX zu s
            char zeit[3]="";        //
            int sec=0;              //
            int platz=0;            //Initialisierungen
            FILE *fp;               //
    
            system("touch zeit");   //Tempdatei anlegen
            fp=fopen("zeit","w");   //die Datei verlinken
            fputs(time,fp);         //die Zeit in die datei schreiben (XX:XX:XX)
            fclose(fp);             //Datei schließen
            fp=fopen("zeit","r");   //Datei oeffnen
    
            fgets(zeit,3,fp);               //Die Stunden auslesen
            platz=atoi(zeit);               //in int umwandeln
            sec=platz*60*60;                //in Sekunden umrechnen
            fseek(fp,ftell(fp)+1,SEEK_SET); //pointer weiterschieben
    
            fgets(zeit,3,fp);               //Die Minuten auslesen
            platz=atoi(zeit);               //in int umwandeln
            sec+=platz*60;                  //in Sekunden umrechnen u. zu den Stunden addieren
            fseek(fp,ftell(fp)+1,SEEK_SET); //pointer weiterschieben
    
            fgets(zeit,3,fp);               //Sekunden auslesen
            platz=atoi(zeit);               //in int umwandeln
            sec+=platz;                     //zu den Stunden u. Minuten addieren
    
            system("rm zeit");      //Datei löschen
            return(sec);            //Sekunden zurückgeben
    }
    


  • bin grad dabei ne neue zu schreiben die ohne Datei anlegen auskommt

    Ja, das würde ich dir auch empfehlen. (am besten ist es, den übergebenen String direkt per sscanf() oder atoi() auszuwerten)

    //1: ssscanf:
    int hr=0,mn=0,sc=0;
    sscanf(time,"%d:%d:%d",&hr,&mn,&sc)
    return 3600*hr+60*mn+sc;
    
    //2: atoi:
    platz=atoi(time);               //Stunden ab Index 0
    sec=platz*60*60;                //in Sekunden umrechnen
    
    platz=atoi(time+3);             //Minuten ab Index 3
    sec+=platz*60;                  //in Sekunden umrechnen u. zu den Stunden addieren
    
    platz=atoi(zeit+6);             //Sekunden ab Index 6
    sec+=platz;
    
    return sec;
    

    PS: Notfalls kannst du das "rm zeit" mal weglassen und nach dem Aufruf nachschauen, was du überhaupt gelesen hast 😉 Oder du schaust dir im Debugger an, was die Funktion macht.



  • hab jetzt einfach deine sscanfmethode übernohmen. Hab jetzt auch den Fehler gefunden,der pointer gab 0 aus, und der String das Richtige. Also zeitum auf string angewendet und es geht 🙂

    getcpu(rdy,string);
    l=zeitum(string);
    
    void getcpu(char *fpoint,char *point)
    {
            int i=0;
            fpoint+=57;
            for(i=0;i<8;i++)
            {
                    *point=*fpoint;
                    point++;
                    fpoint++;
            }
    }
    

    Edit: Danke für deine Hilfe!


Anmelden zum Antworten