Joeran: fgets Problem wenn Datei 0 enthält

Servus,

ich hab ein einfaches Problem mit fgets, welches ich dazu verwende eine Datei mit verschiedenen Einträgen auszulesen.
Ist in einer der Zeilen der Datei ein Eintrag mit 0 bricht fgets anscheinend ab und ließt die nachfolgenden Zeilen nicht mehr aus...
Gibt es da eine Lösung?

Vielen Dank & Grüße

  1. Grüße,
    lass mich raten

    ?
    MFG
    bleicher

    1. nene, einfach nur so:
              $garbagefile='../../../misc/gc.txt';
       if(file_exists($garbagefile)){
        $fp=fopen($garbagefile,'r');
           while($gclist[]=trim(fgets($fp)));
           fclose($fp);
       }
       print_r($gclist);

      und in einer der mittleren zeilen steht halt mal ne 0 und das ist dann der letzte eintrag im gclist-array.

      1. Hallo,

        while($gclist[]=trim(fgets($fp)));

        Da liegt der Hase begraben. "0" ist nämlich in PHP auch false. Und false durch trim jagen ist auch nicht hilfreich.

        Mach lieber so etwas:

        while (($gcelem = fgets($fp)) !== false) $gclist[] = $gcelem;

        (Zum === und !== liest Du Dir besser mal das PHP-Handbuch durch.)

        Viele Grüße,
        Christian

        1. Ah ok, vielen Dank.
          Mir ist bewusst was mit === bzw !== in diesem Fall gemeint ist. :)

        2. Hallo nochmal,

          Mach lieber so etwas:

          while (($gcelem = fgets($fp)) !== false) $gclist[] = $gcelem;

          Äh, da Du ja trim wolltest sowas:

          while (($gcelem = fgets($fp)) !== false) $gclist[] = trim($gcelem);

          Viele Grüße,
          Christian

  2. Hello,

    Gibt es da eine Lösung?

    fgets() und fread() in PHP haben seit einiger Zeit ein Problem. So zumindest meine Meinung!

    Es werden nicht soviele Nutz-Zeichen gelesen, wie Du in Auftrag gibst, sondern ein oder zwei weniger.

    fread() darf z.B. nicht mehr auf 0 Bytes ausgeführt werden. Das ist typischer Juppi-Unsinn. Da wird die Eigensicherheit von Funktionen, die über Genarationen geschaffen wurde, verspielt...

    Liebe Grüße aus Syburg bei Dortmund

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Hallo Tom,

      Es werden nicht soviele Nutz-Zeichen gelesen, wie Du in Auftrag gibst, sondern ein oder zwei weniger.

      Konnte ich bisher nicht nachvollziehen. Beispielcode?

      fread() darf z.B. nicht mehr auf 0 Bytes ausgeführt werden.

      Konnte ich bisher nicht nachvollziehen. Beispielcode?

      Mal ein Beispiel, dass fread() und fgets() korrekt funktioniert:

      <?php  
        
      $fp = fopen ('0datei', 'r');  
      $data = fread ($fp, 5);  
      echo urlencode($data)."\n";  
        
      $fp = fopen ('0datei', 'r');  
      $data = fread ($fp, 10);  
      echo urlencode($data)."\n";  
        
      $fp = fopen ('0datei', 'r');  
      $data = fgets ($fp, 6);  
      echo urlencode($data)."\n";  
        
      $fp = fopen ('0datei', 'r');  
      $data = fgets ($fp, 10);  
      echo urlencode($data)."\n";  
      ?>  
      
      

      hexdump -C 0datei
      00000000  74 65 73 74 00 0a 6e 6f  63 68 65 69 6e 74 65 73  |test..nocheintes|
      00000010  74 0a                                             |t.|

      test%00
      test%00%0Anoch
      test%00
      test%00%0A

      Funktioniert alles wie erwartet.

      Viele Grüße,
      Christian

      1. Hello,

        Es werden nicht soviele Nutz-Zeichen gelesen, wie Du in Auftrag gibst, sondern ein oder zwei weniger.

        Das steht sogar im Manual.
        Das Zeilenende-Zeichen rechne ich hier nicht den Nutzzeichen zu.

        fread() darf z.B. nicht mehr auf 0 Bytes ausgeführt werden.

        Konnte ich bisher nicht nachvollziehen. Beispielcode?

        Es gibt prompt die Warnung, wenn Du versuchst 0 Bytes zu lesen, was in einer Schleife durchaus schon mal passieren kann. Man muss das also selber abfangen, was man fürher nicht musste.

        Warning: fread() [function.fread]: Length parameter must be greater than 0 in
            C:\Programme\xampp\htdocs\test\dateizugriffe\fread.php on line 5

        Liebe Grüße aus Syburg bei Dortmund

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Hello,

          Es werden nicht soviele Nutz-Zeichen gelesen, wie Du in Auftrag gibst, sondern ein oder zwei weniger.

          Das steht sogar im Manual.
          Das Zeilenende-Zeichen rechne ich hier nicht den Nutzzeichen zu.

          Und auch ohne wird nur ein Zeichen weniger gelesen, als beauftragt:

          <?php  ###  fread.php ###

          define ('EL',"<br />\r\n");

          $fh = fopen (__FILE__,'rb');
              $content = fread($fh, 0);

          $content = fgets($fh,10);
              echo "Länge des Content: ". strlen($content) . EL;

          fclose($fh);
          ?>

          Liebe Grüße aus Syburg bei Dortmund

          Tom vom Berg

          --
          Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. Moin!

            Es werden nicht soviele Nutz-Zeichen gelesen, wie Du in Auftrag gibst, sondern ein oder zwei weniger.

            Das steht sogar im Manual.
            Das Zeilenende-Zeichen rechne ich hier nicht den Nutzzeichen zu.

            Und auch ohne wird nur ein Zeichen weniger gelesen, als beauftragt:

            <?php  ###  fread.php ###

            define ('EL',"<br />\r\n");

            $fh = fopen (__FILE__,'rb');
                $content = fread($fh, 0);

            $content = fgets($fh,10);
                echo "Länge des Content: ". strlen($content) . EL;

            fclose($fh);
            ?>

            Ergebnis bei mir (Kommandozeile):

            Warning: fread(): Length parameter must be greater than 0 in /home/sven/test/fread.php on line 6
            Länge des Content: 9<br />

            Wo ist da das Problem?

            fread() akzeptiert (mit sinnvoller Fehlermeldung zurückgewiesen) nicht 0 als Wert der Anzahl zu lesender Bytes.

            fgets() liest maximal (Param-1) Bytes aus der Quelle aus - dokumentiert im Handbuch.

            - Sven Rautenberg

            --
            "Love your nation - respect the others."
            1. Hello,

              Wo ist da das Problem?

              Schau mal vor Deinen Monitor. Da scheint es zu sitzen ;-)

              fread() akzeptiert (mit sinnvoller Fehlermeldung zurückgewiesen) nicht 0 als Wert der Anzahl zu lesender Bytes.

              fgets() liest maximal (Param-1) Bytes aus der Quelle aus - dokumentiert im Handbuch.

              Und was habe ich geschrieben?
              https://forum.selfhtml.org/?t=177685&m=1170790
              "Das steht sogar im Manual."

              Ok, mit Dir muss ich Deutsch reden. Ich werde es mir merken *gg*

              Liebe Grüße aus Syburg bei Dortmund

              Tom vom Berg

              --
              Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
              1. Moin!

                Wo ist da das Problem?

                Schau mal vor Deinen Monitor. Da scheint es zu sitzen ;-)

                Die Antwort hättest du dir schenken können.

                Du jammerst hier über irgendein PHP-Verhalten. Das sich irgendwann man geändert haben soll. Hast aber auch keine wirklichen Belege. Und verzichtest darauf, das Problem deutlich zu beschreiben, indem du - wie man es bei jeder guten Problembeschreibung tut, vgl. auch die Forumshilfe: Tipps für Fragende, dort wörtliches Zitat "Gib an, welche Eingangsdaten Du hast, welche Ausgangsdaten Du erwartest - und was Du abweichend von Deiner Erwartung tatsächlich erhältst." - darlegst, was ist und was stattdessen gewünscht wird.

                fread() akzeptiert (mit sinnvoller Fehlermeldung zurückgewiesen) nicht 0 als Wert der Anzahl zu lesender Bytes.

                fgets() liest maximal (Param-1) Bytes aus der Quelle aus - dokumentiert im Handbuch.

                Und was habe ich geschrieben?
                http://forum.de.selfhtml.org/my/?t=177685&m=1170790&aaf=1
                "Das steht sogar im Manual."

                Du schriebst:

                "fgets() und fread() in PHP haben seit einiger Zeit ein Problem. So zumindest meine Meinung!

                Es werden nicht soviele Nutz-Zeichen gelesen, wie Du in Auftrag gibst, sondern ein oder zwei weniger."

                Im Kontext von "fread() UND fgets() liefern EIN ODER ZWEI Zeichen weniger." war nun wirklich nicht zu erkennen, dass du mit deinem Verweis auf das Manual
                a) nur fgets() meinst
                b) dort das dokumentierte Verhalten von "liefert Wert minus ein Zeichen" meinst.

                In diesem Zusammenhang als Anmerkung: Javascript liefert bei Date.getMonth() Werte von 0 bis 11. Warum auch immer das so ist, es ist so dokumentiert und in allen Browsern implementiert. Niemand kommt auf die Idee, daran was zu ändern.

                Ok, mit Dir muss ich Deutsch reden. Ich werde es mir merken *gg*

                Nein, mit Deutsch reden hat das nichts zu tun. Du solltest aber mal lernen, zu argumentieren und Behauptungen auch zu belegen.

                Auf die von dir angekündigte ausführliche Äußerung zum Thema OOP warten wir auch noch. Kein Wunder, dass du nicht dazu kommst, dort zu antworten, wenn du stattdessen eine neue Baustelle nach der anderen eröffnest.

                - Sven Rautenberg

                --
                "Love your nation - respect the others."
        2. Moin!

          Hello,

          Es werden nicht soviele Nutz-Zeichen gelesen, wie Du in Auftrag gibst, sondern ein oder zwei weniger.

          Das steht sogar im Manual.

          Wo? Link?

          Das Zeilenende-Zeichen rechne ich hier nicht den Nutzzeichen zu.

          Das könnte dann von der Definition von PHP abweichen. Unter dieser Bedingung kann es dann natürlich zu Abweichungen kommen.

          fread() darf z.B. nicht mehr auf 0 Bytes ausgeführt werden.

          Konnte ich bisher nicht nachvollziehen. Beispielcode?

          Es gibt prompt die Warnung, wenn Du versuchst 0 Bytes zu lesen, was in einer Schleife durchaus schon mal passieren kann. Man muss das also selber abfangen, was man fürher nicht musste.

          Wenn man aus einer Datei "nichts" lesen will, dann ist das ein deutliches Zeichen für fortgeschrittenen Unsinn. Die Warnung auszuspucken ist aus meiner Sicht korrekt. Diesen Fall abzufangen also erforderlich. Vernünftige Algorithmen haben das Problem nicht.

          - Sven Rautenberg

          --
          "Love your nation - respect the others."
          1. Hello,

            Wenn man aus einer Datei "nichts" lesen will, dann ist das ein deutliches Zeichen für fortgeschrittenen Unsinn. Die Warnung auszuspucken ist aus meiner Sicht korrekt. Diesen Fall abzufangen also erforderlich. Vernünftige Algorithmen haben das Problem nicht.

            Wieso?
            Unsinn ist es, einen Befehl, der ordnungsgemäß ausgeführt wird, mit einer Fehlermeldung (Warnung) zu belegen.

            Nicht alles, was auf den ersten Blick nicht sinnvoll erscheint, ist deshalb gleich unsinnig!
            In netzwerkfähigen Programmen wird ein "read 0 bytes" z.B. gerne benutzt, um festzustellen, ob der Kanal noch zur Verfügung steht.

            Mir dünkt, dass PHP hier irgendwo ein eigenes kleines Problem haben könnte, was auf diese Weise kaschiert werden soll. Aber das will ich weder untersuchen, noch diskutieren. Ich kann es ja sowieso nicht ändern, dass andere Leute andere Meinungen haben... Und so muss ich PHP eben so hinnehmen, wie es ist. Aber deshalb darf ich es ja doch erwähnen, dass man hier gegenüber älteren Versionen plötzlich etwas zusätzlich beachten muss bei der Benutzung der Funktion.

            Liebe Grüße aus Syburg bei Dortmund

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Hallo Tom,

              Wenn man aus einer Datei "nichts" lesen will, dann ist das ein deutliches Zeichen für fortgeschrittenen Unsinn. Die Warnung auszuspucken ist aus meiner Sicht korrekt. Diesen Fall abzufangen also erforderlich. Vernünftige Algorithmen haben das Problem nicht.

              Wieso?
              Unsinn ist es, einen Befehl, der ordnungsgemäß ausgeführt wird, mit einer Fehlermeldung (Warnung) zu belegen.

              Wenn man 0 Bytes lesen will, dann stimmt wirklich etwas mit dem eigenen Algorithmus nicht. Die PHP-Leute warnen davor, damit man nicht in irgend eine Falle tappt. Ich halte das für absolut unproblematisch - im Gegenteil, ich halte das für sehr programmiererfreundlich, dass so offensichtliche Fehler.

              Nicht alles, was auf den ersten Blick nicht sinnvoll erscheint, ist deshalb gleich unsinnig!
              In netzwerkfähigen Programmen wird ein "read 0 bytes" z.B. gerne benutzt, um festzustellen, ob der Kanal noch zur Verfügung steht.

              Nein, jetzt mal aus Betriebssystemsicht: recv mit der Länge 0 ist GÄNZLICH UNGEEIGNET, um festzustellen, ob eine Socketverbindung noch offen ist. Zumindest unter UNIX (unter Windows dürfte es ähnlich sein, die haben die Sockets auch nur von BSD kopiert) ist es so, dass eine Socketverbindung von der Gegenstelle geschlossen wurde, wenn:

              a) select() oder poll() angeben, dass es zu lesende Daten auf dem Socket
                  gibt

              und

              b) recv() den Wert 0 _zurückgibt_.

              Das Problem mit b) ist (ich hab's selbst nochmal getestet), dass recv() im Falle von "ich will 0 Bytes lesen" *immer* 0 zurückgibt, d.h. man hier keine Fallunterscheidung machen kann! Also ist recv() mit Länge 0 als Parameter _absolut nutzlos_. Mir fällt absolut kein sinnvolles Anwendungsbeispiel ein, wo man Länge 0 lesen wollte. Wenn man das tut, ist der eigene Algorithmus vollkommen kaputt.

              Und in PHP ist das Abfangen von "Socket wurde geschlossen" *VIEL* einfacher: feof() wrappt in PHP genau die nötige Funktionalität und nimmt einem Programmierer genau die Probleme ab, die man sonst damit hat (dass man selbst einen Puffer braucht, um eventuell doch vorhandene Rückgabedaten doch zwischenzuspeichern etc.).

              Mir dünkt, dass PHP hier irgendwo ein eigenes kleines Problem haben könnte, was auf diese Weise kaschiert werden soll.

              Nein, PHP hat hier absolut kein Problem.

              Aber deshalb darf ich es ja doch erwähnen, dass man hier gegenüber älteren Versionen plötzlich etwas zusätzlich beachten muss bei der Benutzung der Funktion.

              Bug #26752. PHP hat bei Socketverbindungen vorher Mist gebaut mit 0 als Längenparameter (Endlosschleife), jetzt wird das abgefangen. Ist aber auch schon 4 Jahre her, dass das gefixed wurde.

              Viele Grüße,
              Christian

        3. Hallo,

          Es werden nicht soviele Nutz-Zeichen gelesen, wie Du in Auftrag gibst, sondern ein oder zwei weniger.

          Das steht sogar im Manual.
          Das Zeilenende-Zeichen rechne ich hier nicht den Nutzzeichen zu.

          Huh? fgets() liest halt ein Zeichen weniger ein, weil Du bei fgets() die Puffergröße (inkl. 0-Byte) angibst und nicht die String-Länge - siehe auch mein Beispiel, wo ich 6 statt 5 übergebe. Das gleiche passiet aber auch in C. Wenn die Funktion nun schon so heißt, wie ihr C-Pendant: Warum sollte sie sich dann nicht auch so verhalten?

          Das war aber schon immer so und ist auch gut dokumentiert. Kann sein, dass Dir das Verhalten nicht gefällt, aber deswegen ist es doch hirnrissig, von "Problemen" mit der Funktion zu sprechen. Siehe Svens Anmerkung: Date.getMonth() ist in Javascript auch sehr seltsam definiert, man mag sich über die Definition aufregen, aber die Funktion selbst ist bezüglich der Definition in allen Browsern korrekt implementiert. "Problem" dagegen impliziert, dass es Bugs gibt, was absolut nicht der Fall ist.

          Viele Grüße,
          Christian

          1. Hello,

            Huh? fgets() liest halt ein Zeichen weniger ein, weil Du bei fgets() die Puffergröße (inkl. 0-Byte) angibst und nicht die String-Länge - siehe auch mein Beispiel, wo ich 6 statt 5 übergebe. Das gleiche passiet aber auch in C. Wenn die Funktion nun schon so heißt, wie ihr C-Pendant: Warum sollte sie sich dann nicht auch so verhalten?

            Was interessiert mich eine Puffergröße oder C, wenn ich PHP programmieren will?
            Wenn ich 10 Bytes anfordere erwarte ich als PHP-Programmierer auch, 10 Bytes zu erhalten, wenn genug da sind und sonst eine Fehlermeldung oder eben weniger und ein eof()== true.

            Und red nicht um den Brei rum, das ist einfach schlampig impelmentiert!

            Das war aber schon immer so und ist auch gut dokumentiert.

            Und weil es immer so war, muss es auch immer so bleiben?
            Vermutlich schon. Die alten DOS-Fehler sind in Windows ja auch oft noch zu finden.

            Kann sein, dass Dir das Verhalten nicht gefällt, aber deswegen ist es doch hirnrissig, von "Problemen" mit der Funktion zu sprechen.

            Es ist unverschämt von Dir, meine Ausage als "hirnrissig" zu bezeichnen.

            Es ist aber durchaus legitim, wenn ich auf mögliche Probleme mit der Funktion hinweise, da sie nachvollziehbar vielen PHP-Programmierern genau an dieser Stelle Schwierigkeiten bereitet.

            "Problem" kann auch bedeuteten, dass man nach dem natürlichen Menschenverstand, den freilich nicht mehr jeder hat [1], ein anderes Verhalten der Funktionen erwarten würde.

            Mit welchem Recht Du mir nun meine Kritik verbieten willst, oder mich dafür als "hirnrissig" darstellen willst, leuchtet mir nicht ein. Du darfst Dich aber dafür entschuldigen.

            [1] Je tiefer man in ein Thema eindringt, desto schwieriger wird es, dieses noch unverbildet und unbeeinflusst von Konventionen zu unlogischen Rahmenbedingugnen zu beurteilen.

            Liebe Grüße aus Syburg bei Dortmund

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Hallo Tom,

              Und red nicht um den Brei rum, das ist einfach schlampig impelmentiert!

              Nein. Es ist vielleicht nicht sonderlich logisch _definiert_ (wie gesagt: getMonths() in Javascript ist ein weiteres Beispiel), aber an der _Implementierung_ selbst ist nichts auszusetzen.

              Das war aber schon immer so und ist auch gut dokumentiert.

              Und weil es immer so war, muss es auch immer so bleiben?

              Wenn Du das Verhalten einer Funktion von heute auf morgen einfach ändern würdest, was meinst Du, wie viele Programme dann plötzlich nicht mehr funktionieren würden?

              Es ist aber durchaus legitim, wenn ich auf mögliche Probleme mit der Funktion hinweise, da sie nachvollziehbar vielen PHP-Programmierern genau an dieser Stelle Schwierigkeiten bereitet.

              Du kommst in einem Posting an und wirfst wieder schwammige Kritik um Dich, dass irgendwelche PHP-Funktionen "Probleme" machen würden - und das liest sich so, als ob die Implementierung dieser Funktionen defekt sei. In diesem Kontext habe ich "Probleme" gelesen. Ich habe es als hirnrissig bezeichnet, so zu argumentieren.

              Wenn Du der Auffassung bist, dass die Semantiken der Funktion nicht wirklich toll sind (und da stimme ich Dir zu) und das auch unmissverständlich rüberbringst, dann sage ich auch nichts weiter.

              Wenn Du aber (wie so oft) einfach nur schwammige Bemerkungen über irgend etwas machst (die sich in der Vergangenheit bei Dir sehr oft als vollkommen substanzlos herausgestellt haben), dann brauchst Du bitte nicht erwarten, dass jeder Dich hier korrekt versteht.

              Betrachten wir mal Dein ursprüngliches Posting und sehen es uns mal an:

              haben seit einiger Zeit ein Problem

              Total schwammig. Impliziert vor allem, dass beide Funktionen vom gleichen Problem betroffen sind.

              Es werden nicht soviele Nutz-Zeichen gelesen, wie Du in Auftrag gibst, sondern ein oder zwei weniger.et

              Wieder total schwammig. Hier wird (in dem Posting alleine) absolut nicht klar, was Du sagen willst. "in Auftrag gibst" impliziert, dass die Funktion sich nicht korrekt verhält, nicht, dass sie einfach anders als erwartet definiert ist. Außerdem "ein oder zwei weniger" deutet darauf hin, dass Du es selbst nicht so genau weißt.

              fread() darf z.B. nicht mehr auf 0 Bytes ausgeführt werden. Das ist typischer Juppi-Unsinn. Da wird die Eigensicherheit von Funktionen, die über Genarationen geschaffen wurde, verspielt...

              Hier sind gleich vier Punkte drin:

              a) "auf 0 Bytes ausgeführt werden" habe ich beim ersten Lesen so verstanden, als ob in der Datei nur noch 0 Bytes übrig wären / die Netzwerkverbindung schon zu wäre. Dann funktioniert fread() aber korrekt.

              b) (siehe dazu v.a. den Rest meiner anderen Postings) Als Du dann endlich erläutert hast, was Du damit genau meinst, wird klar, dass das irgendwie ziemlicher Unsinn ist, den Du da haben willst. Was dann die Glaubwürdigkeit der Kritik selbst nochmal drastisch herabsetzt.

              c) "Juppi-Unsinn": no comment...

              d) "die über Genarationen geschaffen wurde, verspielt": Erst beschwerst Du Dich, dass fgets() unlogisch ist, obwohl es dem C-Standard folgt, dann regst Du Dich aber darüber auf, dass sich fread() angeblich nicht an Konventionen hält. Entscheide Dich doch bitte mal.

              Um mal eine Formulierung anzubieten, die Du in Deinem ursprünglichen Posting hättest verwenden können zu fgets():

              ---------- snip ----------
              Ich möchte Dich noch vor fgets() in PHP warnen, das verhält sich nicht, wie
              ein normaler Mensch es erwarten würde: Statt maximal $puffergroesse Zeichen
              werden nur $puffergroesse - 1 Zeichen eingelesen, wenn eine Zeile mal länger
              als erwartet sein sollte.
              ---------- snip ----------

              Oder irgendwie so ähnlich. Das wäre kurz, prägnant, klar und unmissverständlich gewesen. Dann hätte hier auch keiner etwas gesagt.

              Viele Grüße,
              Christian

              1. Hello,

                Wenn Du das Verhalten einer Funktion von heute auf morgen einfach ändern würdest, was meinst Du, wie viele Programme dann plötzlich nicht mehr funktionieren würden?

                eben das ist eben mit fread() geschehen in PHP.

                Früher hat es erwartungsgemäß reagiert und nicht bei ordnungsgemäßer Benutzung eine Warnung ausgelöst.

                Wenn jemand -1 Bytes anfordert, dann erwarte ich eine Fehlermeldung oder aber, dass die Datei von hinten gelesen wird. Wäre och auch mal eine nette Implementation.

                An der Deklaration der Funktion hat sich übrigens nichts geändert, sondern nur an den "Nutzungsbedingungen", und die gehören zur Implementation. Das war schon immer so *gg*

                Liebe Grüße aus Syburg bei Dortmund

                Tom vom Berg

                --
                Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
                1. Hallo Tom,

                  Wenn Du das Verhalten einer Funktion von heute auf morgen einfach ändern würdest, was meinst Du, wie viele Programme dann plötzlich nicht mehr funktionieren würden?

                  eben das ist eben mit fread() geschehen in PHP.

                  fread() war vorher Buggy beim Lesen von 0 Bytes in bestimmten Zusammenhängen. Nachdem das Lesen von 0 Bytes niemals sinnvoll sein kann, haben die Entwickler beschlossen, den Fall lieber komplett zu verbieten, als zu versuchen, irgend etwas sinnlos zu fixen. Ich kann das gut nachvollziehen.

                  Aber ok, natürlich hast Du recht, dass das Verhalten geändert wurde. Ich sehe das nur im Fall von "Lesen von 0 Bytes" absolut nicht kritisch, weil das sowieso sinnlos ist. Bei fgets() ist es dagegen kritisch, weil die korrekte Angabe der Maximallänge wichtig sein kann.

                  Früher hat es erwartungsgemäß reagiert und nicht bei ordnungsgemäßer Benutzung eine Warnung ausgelöst.

                  Wie oft denn noch: 0 Bytes lesen ist keine ordnungsgemäße Benutzung.

                  Stell Dir vor, Du gehst in den Supermarkt an die Kasse, legst nichts auf das Band und willst dann Zahlen. Du kannst dann zwar sicher aus dem Supermarkt heraus, ohne zahlen zu müssen, aber die Kassiererin wird Dir ohne Artikel keinen Bon ausdrucken lassen, auf dem 0 Euro steht. Wozu auch?

                  Ich halte jeden I/O-Algorithmus, der 0 Bytes lesen will, für kaputt.

                  Wenn jemand -1 Bytes anfordert, dann erwarte ich eine Fehlermeldung

                  Und eine solche wäre in meinen Augen auch bei 0 nicht verkehrt.

                  An der Deklaration der Funktion hat sich übrigens nichts geändert, sondern nur an den "Nutzungsbedingungen", und die gehören zur Implementation.

                  Nein, die gehören ganz klar zur Definition der Funktion. Nicht zur Definition auf Compilerebene, aber wenn ich eine Funktion habe, dann ist das erwartete Verhalten Teil der Schnittstelle, die die Funktion mir bietet.

                  Denn für ein bestimmtes erwartetes Verhalten gibt es sehr viele Möglichkeiten der Implementierung.

                  Nehmen wir zum Beispiel mal Sortieralgorithmen: Wenn ich einen Sortieralgorithmus habe, der mir Daten stabil sortiert und den dann in eine Funktion packe, die das Array als Parameter übergeben bekommt und mir dann das sortierte Array zurückliefert - dann ist die Schnittstelle dieser Funktion "nimm Eingabearray und gebe es sortiert zurück, behalte bei gleichen Werten aber die Ursprungsreihenfolge bei". Wenn ich die Implementierung dann aber austausche, d.h. einen anderen Sortieralgorithmus nehme, dann ändert sich die Definition der Funktion nicht, solange er das Kriterium der Stabilität auch erfüllt.

                  Viele Grüße,
                  Christian

          2. Huh? fgets() liest halt ein Zeichen weniger ein, weil Du bei fgets() die Puffergröße (inkl. 0-Byte) angibst und nicht die String-Länge - siehe auch mein Beispiel, wo ich 6 statt 5 übergebe. Das gleiche passiet aber auch in C. Wenn die Funktion nun schon so heißt, wie ihr C-Pendant: Warum sollte sie sich dann nicht auch so verhalten?

            Der Einheitlichkeit innerhalb der gleichen Sprache halber? fread liest (bis zu) $length Zeichen, fgets nur (bis zu) $length-1. Die Funktion fputs (die nur ein Alias für fwrite ist) schreibt ja auch $length Bytes und nicht $length-1.

            --
            Reden ist Silber, Schweigen ist Gold, meine Ausführungen sind Platin.
            Self-Code: sh:( ch:? rl:( br:> n4:( ie:{ mo:) va:) de:> zu:} fl:| ss:| ls:~ js:|
            1. Hallo,

              Huh? fgets() liest halt ein Zeichen weniger ein, weil Du bei fgets() die Puffergröße (inkl. 0-Byte) angibst und nicht die String-Länge - siehe auch mein Beispiel, wo ich 6 statt 5 übergebe. Das gleiche passiet aber auch in C. Wenn die Funktion nun schon so heißt, wie ihr C-Pendant: Warum sollte sie sich dann nicht auch so verhalten?
              Der Einheitlichkeit innerhalb der gleichen Sprache halber? fread liest (bis zu) $length Zeichen, fgets nur (bis zu) $length-1.

              Das ist aber in C genau so und die PHP-Entwickler haben die C-API kopiert. Muss einem nicht gefallen. Tut es mir auch nicht. Wenn ich ganz ehrlich sein soll, habe ich noch keine Sprache gefunden, bei der mir die I/O-Lib wirklich gefallen hat. Mir ging's hierbei nur darum, zu erläutern, warum die PHP-Funktion so reagiert.

              Viele Grüße,
              Christian