Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

fgets() et nouvelle ligne en fin de fichier (EasyPHP 2.0.0.0/Win)

3 réponses
Avatar
Mounir
Bonjour,

Dans le manuel PHP, à propos de fgets() : "Si une erreur survient,
fgets() retourne FALSE."

J'ai écrit une fonction appelant fgets :

function readline($handle)
{
global $line_num;

//$line=fgets($handle);
$line=fgets($handle);
$line_num++;
if (!$line)
{
debug("Erreur de lecture",false);
exit;
}

return $line;
//return rtrim($line,"\r");
}

Cependant, je remarque que si le fichier se termine par une séquence
nouvelle ligne (style dos) :

1: aaaaaa\r\n
2: bbbbbb\r\n
3: cccccc\r\n

Après le fgets() qui retourne la ligne 3 "cccccc", la fin de fichier
n'est pas atteinte (feof()=false) et le fgets() suivant retourne
FALSE.

Est-ce un problème de retour-chariot spécifique aux OS Microsoft, qui
est codé sur deux caractères ? Merci d'avance.

Cordialement,

--
Mounir

3 réponses

Avatar
Olivier Miakinen

Dans le manuel PHP, à propos de fgets() : "Si une erreur survient,
fgets() retourne FALSE."

J'ai écrit une fonction appelant fgets :

[...]

Cependant, je remarque que si le fichier se termine par une séquence
nouvelle ligne (style dos) :

1: aaaaaarn
2: bbbbbbrn
3: ccccccrn

Après le fgets() qui retourne la ligne 3 "cccccc", la fin de fichier
n'est pas atteinte (feof()úlse) et le fgets() suivant retourne
FALSE.


D'après les commentaires des utilisateurs dans la doc de la fonction
feof(), c'est le comportement habituel de cette fonction, laquelle
retournera FALSE tant qu'on n'aura pas essayé de lire *après* la fin
du fichier. <http://fr2.php.net/manual/fr/function.feof.php>

Est-ce un problème de retour-chariot spécifique aux OS Microsoft, qui
est codé sur deux caractères ? Merci d'avance.


Les rn sont une terminaison normale pour un fichier texte sur Windows,
ce n'est donc pas un problème. Mais bien sûr, s'ils manquent à la fin de
la dernière ligne du fichier, la fonction feof() retournera TRUE après
lecture de cette ligne incomplète puisque fgets() aura atteint la fin du
fichier avant la fin de la ligne.

Du coup, plutôt que de te baser sur feof() pour tester la fin du
fichier, je te suggère plutôt de tester le résultat du fgets() : tant
qu'il lit quelque chose, il retournera une chaîne non vide puisqu'elle
contient au moins un n (ou rn si tu lis en binaire) ; une chaîne
vide marquera donc la fin du fichier.

Avatar
P'tit Marcel

J'ai écrit une fonction appelant fgets :
function readline($handle)
{
global $line_num;
//$line=fgets($handle);
$line=fgets($handle);
$line_num++;
if (!$line)


pas beau. écris plutôt
if($line === false)

car sinon "0" ou "" sera interprété comme false.


Cependant, je remarque que si le fichier se termine par une séquence
nouvelle ligne (style dos) :
1: aaaaaarn
2: bbbbbbrn
3: ccccccrn
Après le fgets() qui retourne la ligne 3 "cccccc", la fin de fichier
n'est pas atteinte (feof()úlse) et le fgets() suivant retourne
FALSE.


"it is not a bug, it is feature"

feof ne renvoit True qu'après une tentative infructueuse de lecture.
Après lecture de la ligne 3, on n'est pas encore en EOF. C'est le mode
de fonctionnement habituel quand on lit des fichiers séquentiels purs
depuis la conception de l'IBM 360 au moins ;-)

Tu n'as pas décrit ta boucle de lecture, mais il faudrait qu'elle
fonctionne comme cela :

$ligne = fgets($handle);
while(!feof($handle)) {
... traitement de $ligne ...
$ligne = fgets($handle);
}



eça
--
P'tit Marcel
stats sur les forums modérés http://www.centrale-lyon.org/ng/

Avatar
Mounir
feof ne renvoit True qu'après une tentative infructueuse de lecture.
Après lecture de la ligne 3, on n'est pas encore en EOF. C'est le mode
de fonctionnement habituel quand on lit des fichiers séquentiels purs
depuis la conception de l'IBM 360 au moins ;-)


Ainsi, il ne faut pas se servir de la valeur de retour de fgets().
J'avais oublié ce mode de fonctionnement, d'habitude (en C/Unix) je
bouclais jusqu'à ce qu'un read/fgets/fread renvoyait 0/EOF :)

Merci ;)