TUTOS.EU

La problématique des sauts de lignes dans les fichiers

Différentes notes sur la problématique des sauts de lignes dans les fichiers

Lorsque l'on crée un nouveau fichier texte par défaut sous Windows

Et qu'on l'ouvre avec Notepad

Le fait d'avoir plusieurs lignes est réalisé à l'aide d'un caractère caché

Si vous ouvrez le même fichier avec NotePad ++

Dans les options vous pouvez faire apparaitre les caractères utilisés par les sauts de lignes

On voit alors que les caractères CR et LF sont utilisés par Notepad pour créer un saut de ligne.
CR signifie carriage return (code ASCII 13)(\r en php)
LF signifie line feed (code ASCII 10)(\n en php)

On pourrait donc penser que Notepad a besoin des 2 pour faire un retour à la ligne

Edit du 17 mai 2015 :

Après test, le code ASCII 10, soit le line feed, \n en php, est traduit en CRLF

là où le code ASCII 13, soit le carriage return, \r en php est traduit par un simple CR.

Aussi utilisez simplement \n, qui s'écrit également CHR(10), et vos sauts de ligne seront correctement interprétés sous Notepad (de Windows 7 toujours).

Par contre, de base en PHP, si vous écrivez dans un fichier, ces caractères CR et LF ne sont pas inscrits même si vous faites un appel à la fonction fputs() pour chaque ligne à écrire

$CheminFichier = './Fichier test.txt';
$monfichier = fopen($CheminFichier, 'w');
fputs($monfichier, 'Ligne 1');
fputs($monfichier, 'Ligne 2');
fputs($monfichier, 'Ligne 3');
fputs($monfichier, 'Ligne 4');
fclose($monfichier);
Lien vers le fichier : cliquez ici Copier le code

Du coup lorsque l'on ouvre le fichier généré, tout apparait sur une même ligne

Pour créer des sauts de ligne avec la commande fputs, on peut utiliser la fonction chr()
On peut indiquer dans cette fonction le numéro d'un caractère ASCII. Dans notre cas on va demander le numéro des caractères qui correspondent à un saut de ligne. Le numéro 13 est celui d'un 'carriage return', soit un retour chariot.

Exemple, avec ce code :

$CheminFichier = './Fichier test.txt';
$monfichier = fopen($CheminFichier, 'w');
fputs($monfichier, 'Ligne 1'.CHR(13));
fputs($monfichier, 'Ligne 2'.CHR(13));
fputs($monfichier, 'Ligne 3'.CHR(13));
fputs($monfichier, 'Ligne 4'.CHR(13));
fclose($monfichier);
Lien vers le fichier : cliquez ici Copier le code

On retrouve ces infos sur AsciiTable.com

Le fichier généré donne ceci :

Le caractère ASCII numéro 10 correspond lui au 'line feed', soit un retour à la ligne.

Le code suivant :

$CheminFichier = './Fichier test.txt';
$monfichier = fopen($CheminFichier, 'w');
fputs($monfichier, 'Ligne 1'.CHR(10));
fputs($monfichier, 'Ligne 2'.CHR(10));
fputs($monfichier, 'Ligne 3'.CHR(10));
fputs($monfichier, 'Ligne 4'.CHR(10));
fclose($monfichier);
Lien vers le fichier : cliquez ici Copier le code

Donne ceci :

Ecrire le code ASCII numéro 13 pour un CR (carriage return) et 10 pour un LF (line feed) revient à faire comme notepad qui utilise les 2.
A noter que lorsque l'on écrit quelque-chose dans une page web en PHP avec echo, \r peut remplacer CR (carriage return) soit CHR(13) et \n peut remplacer LF (line feed) soit CHR(10).

Le code :

$CheminFichier = constant('RacineSite').'admin/Fichier test.txt';
$monfichier = fopen($CheminFichier, 'w');
fputs($monfichier, 'Ligne 1'.CHR(13).CHR(10));
fputs($monfichier, 'Ligne 2'.CHR(13).CHR(10));
fputs($monfichier, 'Ligne 3'.CHR(13).CHR(10));
fputs($monfichier, 'Ligne 4'.CHR(13).CHR(10));
fclose($monfichier);
Lien vers le fichier : cliquez ici Copier le code

Résultat :

Ici on va écrire des CR et LF avec différentes combinaisons. Le code :

$CheminFichier = constant('RacineSite').'admin/Fichier test.txt';
$monfichier = fopen($CheminFichier, 'w');
fputs($monfichier, 'Ligne 1'.CHR(10).CHR(13));
fputs($monfichier, 'Ligne 2'.CHR(10).CHR(13));
fputs($monfichier, 'Ligne 3'.CHR(10).CHR(13));
fputs($monfichier, 'Ligne 4'.CHR(10).CHR(13));

fputs($monfichier, 'Ligne 1'.CHR(10));
fputs($monfichier, 'Ligne 2'.CHR(10));
fputs($monfichier, 'Ligne 3'.CHR(10));
fputs($monfichier, 'Ligne 4'.CHR(10));

fputs($monfichier, 'Ligne 1'.CHR(13));
fputs($monfichier, 'Ligne 2'.CHR(13));
fputs($monfichier, 'Ligne 3'.CHR(13));
fputs($monfichier, 'Ligne 4'.CHR(13));

fputs($monfichier, 'Ligne 1'.CHR(13).CHR(10));
fputs($monfichier, 'Ligne 2'.CHR(13).CHR(10));
fputs($monfichier, 'Ligne 3'.CHR(13).CHR(10));
fputs($monfichier, 'Ligne 4'.CHR(13).CHR(10));

fclose($monfichier);
Lien vers le fichier : cliquez ici Copier le code

Voici ce que cela affiche avec Notepad ++

Quand on affiche le même fichier avec Notepad, on se rend compte que seul la combinaison CR (carriage return) + LF (line feed) permet d'être interprétée comme un retour à la ligne par Notepad, là où Notepad++ se contente de CR, LF, ou encore CRLF etc...

On va maintenant récupérer les valeurs d'un champ de saisie multiple d'une page Web.

Voici le code du champ de saisie multiple

<textarea name="TxtContenuFichier" id="TxtContenuFichier" cols="80" rows="2">Ligne 5
Ligne 6
Ligne 7
Ligne 8</textarea>
Lien vers le fichier : cliquez ici Copier le code

On va lire le contenu du champ de saisie multiple en PHP et l'écrire dans un fichier avec la fonction fputs() :

$TxtContenuFichier = $_POST['TxtContenuFichier'];

$nomfichier = 'MonfichierAvecLesValeurs.txt';
$CheminFichier = './'.$nomfichier;
$monfichier = fopen($CheminFichier, 'w');
fputs($monfichier, $TxtContenuFichier."");
fclose($monfichier);
Lien vers le fichier : cliquez ici Copier le code

Quand on récupère le fichier txt généré localement sur un pc Windows, les sauts de lignes sont les mêmes qu'avec Notepad, à savoir un CR (carriage return) + LF (line feed)

Par contre si on édite le fichier en ligne directement depuis WinScp en utilisant Notepad++, alors un caractère CR (carriage return) apparait en plus

Si on ajoute une ligne en plus dans ce même fichier, le saut de ligne est alors symbolisé par un simple carriage return.

Si on sauvegarde le fichier et qu'on le réouvre, alors les CR des nouvelles lignes ajoutées ne sont plus présents. De ce fait l'affichage se passe mal et ce qui a été ajouté est mélangé avec d'autres lignes.

Après multiples tests, je n'ai pas réussi à lever le problème. Je pense à un Bug spécifique à l'édition d'un fichier au travers de WinScp.

J'ai par exemple essayé lors de la création du fichier de supprimer une éventuelle suite de carriage return avec le code ci-dessous sans succès.

$UneChaine = preg_replace('/\r+/',CHR(13),$UneChaine);

Pour information voici où paramétrer WinScp pour que Notepad ++ soit l'éditeur par défaut des fichiers

Pages Web

Site WebDescription
CHR function sur PHP.netExplication sur la fonction CHR()
PHP.net et séquences d'échappementExplique ce qu'est par exemple \n ou \r

Article(s) précédent(s)

2