fseek an vorher gemerkte Position zurückkehren



  • Hallo 🙂

    Ich habe eine Frage zu fseek.

    Und zwar merke ich mir in meinem Programmcode mit

    pos = ftell(FilePTR);
    

    eine bestimmte Stelle, zB pos = 3452

    gehe dann wieder mit rewind an den Anfang der Datei, mache da etwas ( weit vor Position 3452) und möchte danach wieder an die pos. 3452 zurückkehren.
    Dies habe ich einmal mit

    fsetpos(FilePTR, &pos);
    

    probiert und einmal mit

    fseek(FilePTR, pos, SEEK_SET);
    

    Beide Funktionen bekommen auch die richtige Position übergeben und sind true.
    Jedoch steht in meinem

    char input[255];
    

    danach nicht die Zeile ab Pos 3452 sondern noch die "aktuelle Zeile", von wo aus ich eigentlich zurückspringen möchte.

    Wenn ich jedoch

    fgets(input,255,FilePTR);
    

    verwende, gelange ich in die nächste Zeile nach pos 3452, aber nicht an den Anfang dieser Zeile, sondern irgendwo mittendrin.

    Wie setz ich also

    fseek
    

    oder

    fsetpos
    

    richtig ein, damit er an die gemerkte Position zurückkehrt, die ich danach weiter einlesen kann, also in meinem "input" auch wirklich diese Zeile steht, und nicht die alte?

    Danke! 🙂



  • Der Rückgabewert von ftell ist nicht unbedingt für fsetpos geeignet.

    Zeig mal bitte deinen Code, damit man sieht, was du falsch machst.
    Auch wie du die Position für pos findest.



  • für fsetpos habe ich fgetpos genommen, sorry fürs nicht hinschreiben

    also ich lese ein *.unv file ein und befinde mich am Anfang einer Zeile und möchte mir diese Position merken. in input speichere ich immer die aktuelle Zeile, die gerade eingelesen wird

    char *charZgr = NULL;
    
    [...]
    
    charZgr = input;
    
    // merken der aktuellen Zeile 
    //fgetpos(FilePTR, &pos);
    pos = ftell(FilePTR);
    
    rewind(FilePTR);
    
    // abgekürzt: suche eine bestimmte Zeile, die ich finde und lese dort Sachen ein
    charZgr = strstr(input,"15"); 
    							fgets(input,255,FilePTR);
    
    sscanf(charZgr, "%f %f %f %f %f %f %f", &block15[0], &block15[1], &block15[2], &block15[3], &block15[4], &block15[5], &block15[6]);
    
    // nach dem abspeichern der Werte möchte in nun an meine vorher gemerkte pos zurückspringen
    
    if(fseek(FilePTR, pos, SEEK_SET) == 0) 
    {
    charZgr = input; // so hat er noch die Zeile von den eben eingelesenen Werten
    
    // wenn ich noch fgets dazuschreibe ist er in der nächsten Zeile von pos 3542 , jedoch mittendrin
    fgets(input,255,FilePTR);
    
    }
    

    unv file :

    [...] // Zeile die ich nach rewind gesucht habe, von der aus ich an pos zurückspringen möchte
    101         0         0         9   3.0000e+01   0.0200e+00   1.3200e+02
    [...]
    
    // 101 ist die Zeile in die ich gehe und mir die position merke
    101       102       103       101         0       105       104         0
    103       108       106       107       108         0       107       104
    // wenn ich fgets mache steht in input " 0       107       104"
    

    Wie bekomme ich in input wieder die Zeile von pos 3542? bzw vll auch nach Zahl 101



  • entchen schrieb:

    if(fseek(FilePTR, pos, SEEK_SET) == 0)
    {
    charZgr = input; // so hat er noch die Zeile von den eben eingelesenen Werten
     
    // wenn ich noch fgets dazuschreibe ist er in der nächsten Zeile von pos 3542 , jedoch mittendrin
    fgets(input,255,FilePTR);
     
    }
    

    Das charZgr = input; noch keinen Einfluss auf den Inhalt hat ist klar, da du ja erst aus der Datei lesen musst.

    Woher weißt du, dass die Stelle für das ftell richtig ist?
    Liest du vorher Werte ein und vergleichst die? Dann steht der Dateizeiger (Schreib/Lesezeiger) hinter diesen Werten. Da wird die Position gemerkt, nicht die Zeile.

    Du kannst dir vor dem fgets schon die Position mit ftell holen. Wenn du sie dann brauchst, nimmst du diese.

    Ich hoffe input hat auch gültigen Speicher.



  • beim debuggen habe ich mir angeguckt welchen Wert pos bei ftell bekommt und dann an der stelle von fseek welche pos er übergegeben bekommt, beide WErte waren identisch und fseek liefert auch 0 zurück

    input :

    char input[255];
    

    wenn ich 2 mal fgets mache kommt er auch an den Anfang der übernächsten Zeile. Jedoch ist dies keine brauchbare Lösung für mich, weil ich immer die Positiond er akutellen Zeile später speichern möchte

    oder meinst du ob die pos von ftell allein schon falsch ist?
    das könnte glaub ich der Fehler sein.

    ich habe im unv file die Zeichen gezählt und 3542 liegt genau da wo er nach fgets hinspringt. Aber wieso ?

    eine Zeile vor 101 102... steht noch ein name...

    ...den lese ich ein, speicher ihn mir ab, srpinge in die nächste Zeile und dann
    setz ich dort ftell ( wie im code ), fgetpos gibt mir genau dieselbe Zahl zurück

    [...]
    name
    101       102       103       101         0       105       104         0
    

    [...]

    sscanf(input,"%s", kompName);
    
    // Komponentennamen eingelesen --> ín nächste Zeile springen
    fgets(input,255,FilePTR);
    
    charZgr = input;
    
    // merken der aktuellen Zeile in Block 82
    //fgetpos(FilePTR, &pos);
    pos = ftell(FilePTR);
    
    // [...] siehe Kommentar davor
    

    Wie merke ich mir dann die richtige position?

    Konkret möchte ich eigtl, dass ich 101 einlese, mir die Position dahinter merke, dann in Zeilen davor gehe, etwas mache, und danach wieder an die gemerkte Position zuürckkehre um 102 einzulesen, usw.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum C (C89, C99 und C11) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ich glaube, es liegt daran, dass das Position bestimmen/wieder anspringen und das formatierte Lesen (fgets interpretiert zB unter Windows 0x0a 0x0d als ein Zeichen (\n)) nicht zusammen passen. Öffne die Datei mal im Binär-Modus und experimentiere damit ein bisschen herum.



  • Verwende fsetpos/fgetpos mit einer fpos_t-Variablen; das ist einfacher und weniger fehleranfällig als ftell/fseek.



  • Bei fgetpos habe ich aber leider dasselbe Problem wie ftell... die falsche Position...
    Was kann ich anders machen?



  • Hast Du mal versucht, die Datei im Binär-Modus zu öffnen und zu verarbeiten?
    Ansonsten könntest Du noch
    a) die ganze Datei einlesen und nur im Speicher hin- und herpositionieren
    b) für das 'dann in Zeilen davor gehe, etwas mache'
    die Datei ein zweites Mal öffnen, lesen, verarbeiten wieder schließen und mit dem ersten unveränderten Filestream sequentiell weiterlesen



  • okay danke,

    ich versuch es jetzt mal im Binärmodus. bzw habe es versucht

    nun ist die Position 3398. d.h. die ist am Ende der Zeile in der ich mich befinde.
    Jedoch möchte in den Zeiger gerne am Anfang der Zeile bzw wenn es geht hinter der Zahl 101 haben.

    Gibt es dafür eine einfache Möglichkeit, wenn die Anzahl der Zeichen immer variiert, je nachdem in welcher Zeile man ist und sich die Position merkt.

    Danke 🙂



  • Bei mir funktioniert das einwandfrei, wenn ich die Datei im Binärmodus öffne und nach fgets mittels ftell die Position lese, mir merke und später mit fseek wieder anspringe.
    Achtung: Das folgende Testprogramm enthält Elemente aus C++:

    #include <cstdio>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int main(int argc, char **argv)
    {
       FILE *pfile = fopen(argv[1], "rb");
    
       char buf[255];
       vector<long> v;
       v.push_back(0);
    
       while(fgets(buf, 255, pfile))
       {
          cout << buf;
          v.push_back(ftell(pfile));
       }
    
       v.pop_back();
       random_shuffle(v.begin(), v.end());
       cout << "\n\n";
    
       for(int i = 0; i < v.size(); ++i)
       {
          fseek(pfile, v[i], 0);
          fgets(buf, 255, pfile);
          cout << buf;
       }
    
       fclose(pfile);
    }
    


  • Irgendwie werde ich aus den Angaben nicht schlau, was wann wie wo eingelsen wird.
    Da fehlt immer etwas.
    Bitte kKonkreten minimalen Code, der den Fehler ergibt. Mit Angabe der Datei die du bearbeitest.

    (Psst Belli, mittlerweile sind wir im C-Teil vom Forum gelandet)



  • Danke an alle.

    Konnte das Problem jetzt hoffentlich lösen.

    Ich habe nun

    pos = pos - strlen(input) +1;
    

    gemacht. Damit komme ich immer an die richtige Stelle


Log in to reply