pointer auf Datei, Problem theorethisch lösen



  • gut dass du dich meldest wutz, dann kann die lösung nich fern sein.

    nun ja, normalerweise, wie auch bei diesem projekt, mach ich das so:

    Beispiel:

    int main(void){
    
      FILE* dat;
    
      if((dat=fopen("bsp.txt","w"))== NULL){
         printf("Fehler beim Öffnen --> errno=%d", errno);
         return -1;
      }
      else
         fclose(dat);
    
      return 0;
    }
    

    der Fehler taucht, beim zweiten Durchgang hier auf:

    if((dat=fopen((const char*)settings.FILENAMES[FILE_ANSWERS], "w")) == NULL)
    

    sprich, ich komm gar nicht dazu errno abzurufen... Die Fehlermeldung hab ich grad
    nicht zur hand, weil ich grad nich @home bin, die folgt später (also die genaue
    Fehlermeldung halt)...
    Ungefär lautet sie so:

    The Acess to Read at 0x9923bb32 from 0x0031221bc is forbidden

    so ungefär halt, ich schau später noch mals nach...

    gruss
    ITEDVO



  • itedvo schrieb:

    int main(void){
      
      FILE* dat;
    
      if((dat=fopen("bsp.txt","w"))== NULL){
         printf("Fehler beim Öffnen --> errno=%d", errno);
         return -1;
      }
      else
         fclose(dat);
    
      return 0;
    }
    

    Das macht man besser so:

    if( dat=fopen("bsp.txt","w") )
    {
      ...
      fclose(dat);
    }
    else
    {
      perror("bsp.txt");
      return -1;
    }
    

    Der Cast ist sowas von häßlich, lass mich raten, du compilierst wieder mal als C++?
    Die Fehlermeldung lässt auf eine ungültigen Speicherzugriff schließen, also
    entweder settings oder settings.FILENAMES ist undefiniert oder FILE_ANSWERS ist außerhalb definierter Grenzen oder ...
    fopen ist komplett unschuldig daran, wirst du irgendwann merken.



  • das war ja dass was ich wissen wollte...
    und nein ich compiliere nicht unter c++

    hmm, ich hab das ganze jetzt mal mit F10/F11 durchgearbeitet... es ist alles korrekt
    initialisiert, vieleicht hab ich auch was übersehen... ich schau noch mals nach
    und meld mich dann vom laptop aus noch mal...



  • Ich plädiere auf Speicherüberschreibung...
    schau mal ob vorm 2. fopen mit settings auch alles passt ...



  • ihr hattet wie immer recht... hab den fehler jetzt gefunden, es lag daran, dass
    die anzahl der Fragen anstatt überschritten addiert wurde. Hatte nämlich eine
    Funktion geschrieben welche einen String in eine Dezimalzahl umwandelt...

    zum beispiel:

    "123321" --> 12332110

    nur hab ich vergessen die übergeben Variable auf 0 zu setzen...

    void Wc2i(int *zahl, char text[]){
    
    	int leng;
    	int mult=1;
    
    	*zahl=0; // hat gefehlt
    
    	for(leng=0; text[leng+1]!='\0'; leng++);
    
    	for(leng; leng > -1; leng--){
    		if(text[leng] < 48 || text[leng] > 58)
    			break;
    		(*zahl)+=((int)text[leng]-48)*mult; // weil *zahl=0 gefehlt hat, wurde zum beispiel zur 5, 5 addiert... so ergab es 10 anstatt 5... jetzt gehts
    		mult*=10;
    	}
    
    }
    


  • Sorry, da muss ich jetzt ein bisscen klugscheißen.

    1. Dafür gibt es strtol()

    2. Kannst du die beiden Schleifen auch zu einer zusammenfassen.

    3. Statt 48 solltest du '0' und statt 59 ';' schreiben.
    Oder besser isdigit() falls doch nur Zahlen gemeint sind

    4. Brauchst du nicht mult * 10 nehmen sondern die Zahl * 10

    zahl = 0;
    solange Ziffern da sind
      zahl = zahl * 10 + (Ziffer - '0')
    

    5. Haben Funktionen einen Rückgabewert, denn man genau für solche Funktionen benutzen soll.



  • 3. ... statt 58 ':' schreiben. 🙄

    (Immer die mit der großen Klappe) 😡



  • verbesserungen sind eh immer willkommen, doch dadurch das INT und CHAR zur gleichen
    Obergattung (Ganzzahlen) gehört, kann man ruhig im Dezimalen arbeiten...
    weiter wird in meiner Ausbildung wenig auf Standard-Bibliotheken zurück gegriffen.
    Na gut es kommt auf den Professor drauf an der Unterrichtet.

    Und aus Fehlern lernt man...

    und nein, so wie ich das mach kann ich eben nicht beide schleifen zusammennehmen.
    bei einer wird der zähler vergrößert und bei der anderen verringert...

    weil die zahl 234121 in form eines Strings is so: "234121"... die 1 befindet sich beim Index 5 und nicht 0... diese 1 wird in eine Dezimale umgewandelt
    mit mult (=1) mulitpilizert und zur zahl hinzuaddiert (zahl = 1)... danach wird index
    um 1 reduziert und mult mit 10 multipiliziert... jetzt stehen wir am index 4...
    index 4 enthält die zahl 2 an der 10er stelle was den wert 20 aufweist... 2 wird
    ins dezimale umgewandelt, mit mult multipliziert (*10) und zur zahl hinzuaddiert.
    in zahl steht jetzt 21...

    usw.



  • itedvo schrieb:

    verbesserungen sind eh immer willkommen, doch dadurch das INT und CHAR zur gleichen
    Obergattung (Ganzzahlen) gehört, kann man ruhig im Dezimalen arbeiten...

    Das kann man zwar, aber wenn man zum Beispiel statt des ASCII-Codes 48 das Zeichen '0' verwendet, erhöht das die Lesbarkeit deutlich. Bei '0' weiß jeder sofort, was gemeint ist, während man, wenn man eine 48 sieht, erst einmal überlegen muss, was überhaupt gemacht wird.



  • void Wc2i(int *zahl, const char *text)
    {
      *zahl=0;
      while( *text>='0' && *text<='9' )
      {
        *zahl*=10;
        *zahl+=*text++-'0';
      }
    }
    

    - Minuszeichen-Auswertung fehlt noch
    - Fehlerbehandlung/Wertebereichsprüfung fehlt noch
    - statt void kann man den Rückgabewert einer Funktion viel besser nutzen, z.B. für das Ergebnis bzw. einen Fehlercode
    - Casting auf int ist bei numerischen Operationen völlig überflüssig, da hierbei der Standardtyp schon int ist
    - ...



  • nun ja, dass mit der Lesbarkeit stimmt schon...

    @wutz: wegen dem cast auf int: hab ich für mich zur lesbarkeit gemacht, weiss nich,
    is so ne angewohntheit von mir...



  • Danke Wutz!


Anmelden zum Antworten