Grundsatzfragen zu Dateioperationen und fgets



  • 1.)Wenn ich eine Datei geöffnet und danach wieder geschlossen habe, steht der Dateizeiger(vorausgesetzt ich habe a oder a+) benutzt am Dateiende. Wenn ich die Datei mit r wieder öffne, steht der Dateizeiger dann immer noch am Ende? Oder nur wenn ich die Datei wieder mit a oder a+ öffne?

    2.)Im Normalfall liest doch fgets Zeilenweise aus einer Datei bis zum \n oder EOF ... gibt fgets in dem Fall immer nur eine Zeile aus und schiebt den Dateipositionszeiger eine Zeile weiter? Was passiert wenn ich zwischendurch die Datei wieder schließe?

    3.) Falls 2. so nicht geht, was mache ich dann? Muß ich mir dann eine Varibale basteln, die dann irgendwie den Dateipositionszeiger eine Zeile weiter schiebt, geht das überhaupt?

    Ich habe nämlich folgendes vor, eine Funktion soll Daten in Form von Zahlen (max. 3 Stellig) auslesen und dann an eine Variable übergeben. Beim nächsten Aufruf der Funktion soll dann die nächste Zeile ausgelesen und wieder an die Variable übergeben werden usw. bis irgendwann das Ende erreicht wurde. Die Übergabe erfolgt dann über einen char in den fgets rein schreibt und der dann weiter verwendet wird (wie groß wähle ich dann den char?) ...



  • 1.)Wenn ich eine Datei geöffnet und danach wieder geschlossen habe, steht der Dateizeiger(vorausgesetzt ich habe a oder a+) benutzt am Dateiende. Wenn ich die Datei mit r wieder öffne, steht der Dateizeiger dann immer noch am Ende? Oder nur wenn ich die Datei wieder mit a oder a+ öffne?

    Der Dateizeiger steht dann grundsätzlich - beim Neuöffnen - wieder am anfang der Datei.



  • Es wäre sinnvoller wenn du den Filepointer geöffnet lassen würdest und dann eine Zeile nach der anderen liest.
    Falls das nicht geht könnte das helfen

    char Daten[80+1];
    
    int myGetNextItem(char *Datem,char *filename)
    {
     FILE *fp;
     static unsigned long Position=0;
     if (0==(fp=fopen(filename,"rt"))
      {
       // Fehlermeldung
      return 1;
      }
     fseek(fp,Position,SEEK_SET);// positionieren
     fgets(Daten,80,fp)          // lesen
     Position=ftell(fp);         // position merken
     if (0!=feof(fp))            // eof feststellen
      {
      // Fehlermeldung past end of file
      fclose(fp);
      return 2;
      }
     fclose(fp);
     return 0;
    }
    


  • Hallo DAB,

    danke für den Tip, hatte schon so etwas in der Art vermutet. Allerdings habe ich noch ein paar Fragen ...
    Was genau macht der Parameter "rt" ? r alleine ist klar, aber mit t habe ich das noch nicht gesehen, ist auch in unserer Sprachbeschreibung nicht aufgeführt. In der Hilfe vom Programm wird auch rt benutzt, ich kann aber nicht erkennen warum das so ist.
    Dann habe ich auch nicht verstanden warum du den Pointer auf filename stellst bzw. wie ich dann den Dateinamen vorher an gebe, so das dann auch die richtige Datei geöffnet wird.
    Weiter verstehe ich auch nicht so genau, warum du 3 unterschiedliche Returnwerte aus gibst. Ich nehme mal an, weil man die dann in der Main noch mal abfragen könnte um dann je nach Rückgabewert darauf reagieren zu können.

    Jetzt noch mal zu dem Ablauf, wenn ich das so mache wie du vorgeschlagen hast, dann setze ich jedes Mal wenn ich die Funktion aufrufe die Position wieder auf 0, das will ich aber nicht, da die Funktion so oft aufgerufen werden soll bis z.B. das Dateiende erreicht wurde .. also definiere ich Position schon mal global, oder? Genau so wie das Schließen der Datei, du machst zum Schluß jedes Mal ein fclose ... Angenommen ich lasse die Funktion durch eine if Schleife so oft durch laufen wie es nötig ist, dann müßte ich doch vorher schon die Datei öffnen und erst dann schließen wenn ich mit der If Schleife fertig bin, oder?
    Ne andere Möglichkeit wäre wahrscheinlich den Positionszeigerwert irgendwo zu speichern, beim nächsten Durchlauf wieder abrufen und den Zeiger dahin verschieben, aber das erscheint mir zu umständlich.

    Im Moment bin ich allerdings ziemlich verwirrt, da ich den ganzen Vormittag damit verbracht habe das so hin zu bekommen das es einigermaßen läuft ... wahrscheinlich sehe ich schon den Wald vor lautere Bäumen nicht mehr. Denn mein nächstes Problem ist nämlich die Übergabe von dem Wert, der ja nach jedem Durchlauf der Funktion im meinem Feld ein anderer ist, an eine Variable mit der ich dann weiter rechnen kann.
    Andererseits ergibt sich daraus dann die Frage ob die Übergabe an den Char unbedingt notwendig ist und ich nicht den ausgelesenen Wert direkt an eine Variable übergeben kann mit der ich dann weiter machen kann. Zumindest müßte ich eine Möglichkeit haben die Zeichenkette aus dem char in den benötigten double Wert umzuwandeln.

    Viele Fragen, ich weiß ... ich hoffe aber trotzdem das ich die eine oder andere brauchbare Antwort bekomme. Auch wenn ihr vielleicht den Kopf schüttelt und der Meinung seid ich sollte mit C noch mal komplett von vorn anfangen, hoffe ich auf eure Hilfe und wenn es nur ein paar Erklärungen sind. Denn unsere Lehrer ziehen ihren Stoff an Hand eines Scriptes durch und gehen nicht auf Detailfragen ein.
    Diese Aufgabe war übrigens ein Versuch mal etwas anderes als das was im Lernmodul steht zu versuchen!

    Nebenbei bemerkt muß ich mich auch noch gleichzeitig mit Assembler und SPS beschäftigen 😞 😞



  • ➡ Parameter rt
    In der PC Welt bigt es die die modi t und b t steht für textmode b steht für binaer. In der Unix welt ist dieser Parameter unbekannt. Das muß damit zusammenhängen das irgemdwann irgendjemand meinte eine Zeile musse mit CR (carriage return = Wagenrücklauf) lf (linefeed Zeilenvorschub) beendet werden, während die meisten meinten eine LF wär ausreichend. Damit man jetzt beide arten von Zeilenende mit fgets und ähnlichen beasrbeiten kann gibt es den Parameter t dann wird CrLf als Zeilenende betrachtet. ein \n im fptintf erzeugt dann auch ein CrLf im b mode verhält es sich so wie im Rest der Welt.

    Deine Annahme bezüglich der returnwerte ist richtig 0 heißt alles ist in Ordnung != 0 hießt irgendetwas ging schief. Da für das Schiefgehen sehr viele möglichkeitn hat kann man diese auch ausnutzen. Im aufrufenen programm reicht dann ja ein

    ➡

    if (0!=funktion())
     {
      //errorhandling
     }
    

    Wenn man es braucht kann man dan auch etwas genauer auflösen.

    ➡ da ich in der routine static vor die Position geschrieben habe, wird im allerersten Aufruf die Variable mit 0 initialisiert bei jedem foolgenden Aufruf hat sie das Ergebnis des letzten Aufrufs

    Dein erster Text sagte eigentlich das du fopen und fclose machen willst
    sonst ist es trivial
    Mit einer einer for oder while (nicht if) Schliefe geht es wie folgt

    char Daten[80+1];
    ....
     if (0==(fp=fopen(filename,"rt"))
      {
       // Fehlermeldung
      return 1;
      }
    
     while ( 0!=fgets(Daten,80,fp))
     {
      //Tu was mit den Datem
     }
    
     fclose(fp);
    

    ➡ UM die in dem String gelesenen Daten in eine Zahl umzuwandeln nimmt man für floats am besten

    char Daten[80+1];
     char   *stopstring;
     double x;
     strcpy(Daten,"3.141");
    
       x = strtod( Daten, &stopstring );
       if (0!=strlen(stopstring));
        {
         // Errorhandling Fehler in Zahlenkonvertierung
        }
    

    Für signed und unsigned int gibt es noch strtol, strtoul die ähnlich funktionieren.

    Wenn du mit den Script der Vorlesung nicht zurechkommst gibt es noch 2 Möglichkeiten:
    👍 Besorg die ein Fachbuch zum lernen
    👍 hier auf C++ gibt es sehr gute Tutorials, die man durcharbeiten kann.

    Noch ein Typ im Internet gibt es etliche Referenzen zu den Funktionen von C, dort kann man
    - a nachlesen wie eine Funktion funktioniert und
    - b sind oftmals Beispiele für die Anwendeung der Funktionen dabei

    Eine gute Quelle ist auch die Online Version der MSDN.

    oder hier http://www.cppreference.com/



  • Das hört sich doch schon mal interessant an, allerdings sehe ich die Funktion strtod zum ersten mal 😉

    Das es alles so sein muß wie ich zuerst geschrieben hatte ist keine Bedingung, aber es war für mich so am einfachsten. Wenn die ganze Geschichte anders zu lösen ist, bin ich dafür auch offen.

    Tutorials habe ich mir schon einige angesehen, aber meistens findet man darin nicht das was man braucht. Die gängigen Sachen tauchen überall wieder auf, aber z.B. das mit dem strtod habe ich noch in keinem gefunden.
    Die meisten Standard Geschichten gibt unsere Sprachbeschreibung ja auch her, zumindest das was nachher Prüfungsrelevant ist. Da hat man eh nicht viel Zeit noch nach anderen Dingen zu suchen bzw. auch gar keine Gelegenheit, da diese Prüfung schriftlich ausgeführt wird.
    Dieses Programm was ich mir basteln möchte soll nur eine Vorbereitung für die Projektwoche sein, damit ich ein paar Eventualitäten schon vorweg mal ausprobiert habe.

    Im Grunde hast du aber Recht, wenn man das Thema weiter verfolgen möchte sollte man auf Fachbücher zurück greifen! Ich hoffe trotzdem das ich noch die eine oder andere Frage stellen kann und auch eine Antwort bekomme ... und wenn es nur ein Schubs in die richtige Richtung ist 😕
    Werde mich morgen nach der Frühstückspause weiter damit beschäftigen.

    Danke !! 🙂


Anmelden zum Antworten