Page 1 sur 1

Petit problème : Trouver et remplacer un caractère NUL

Publié : jeu. 25/mars/2010 12:14
par Malo
Bonjour

Une des lignes de mon fichier texte est composée comme suit :
- des valeurs numérique
- des séparateurs (;)
- des caractères NULL chr(0) , ici après 37
- et des caractères retour chariot chr(13) + saut de ligne chr(10) a la fin de la ligne

5283;0572;1040; 760; 91;2086; 10; 2; 10; 0;0310; 3; 37; ;0343; 01

je voulais mettre une pièce jointe pour l'exemple mais je ne vois pas comment ... pouvez vous m'indiquer la démarche, merci.
Le problème si vous recopiez simplement cette ligne dans un fichier txt, les NUL se transforme en blanc.

Je voudrais supprimer les caractères NUL chr(0) hexa(00) et les remplacer par une autre valeur ex:chr(32).

Code : Tout sélectionner

;pour localiser chr(0)
ReadFile(0,"C:\leFichier.txt")
While Eof(0)=0
ligne.s=ReadString(0)
char=FindString(ligne.s,Chr(0),1)
lg=Len(ligne.s)
Wend
CloseFile(0)
Quand j'emploie " ReadString(#Fichier [, Options])" la lecture s'arrête au premier chr(0),
ce qui parait normal car La doc dit:

"NUL (NULL) : caractère nul
Typiquement (et spécialement en PureBasic) utilisé pour indiquer la fin d'une chaîne."

Pourtant pour la commande ReadString la doc dit:

" Lit une chaîne de caractères à partir du #Fichier spécifié, jusqu'au prochain retour chariot
(les formats de fichiers texte DOS, Unix et MacOS sont supportés).
Si le paramètre 'Option' n'est pas spécifié, la chaîne de caractères est lue au format UTF-8 si
le programme est compilé en mode unicode, sinon la lecture s'effectue en ASCII. "


Avec un éditeur hexa j'arrive à les localiser, mais je ne trouve pas le moyen
de le faire avec PB 4.31.

Une autre solution pour supprimer ce chr(0) serait de pouvoir enregistrer depuis PB ce fichier sous
un format txt correct, sans passer par Requester, et là je ne vois pas comment procéder non plus.
J'ai essayé de créer un fichier txt avec CreateFile et de copier le fichier dedans avec CopyFile, mais
cela me donne exatement le même fichier.

Je pense que PB peut surmonter ces problèmes, mais avec mes connaissances actuelles je suis bloqué.

Je vous remercie par avance pour votre aide

Re: Petit problème : Trouver et remplacer un caractère NUL

Publié : jeu. 25/mars/2010 13:09
par Ar-S
Bonjour,
Pour faire suivre une pièce jointe :
Je t'invite à regarder la liste d'hébergeurs que j'ai placé ici : http://www.purebasic.fr/french/viewtopi ... 49#p111249

Pour ton soucis, pourquoi ne pas tenter de mettre tout le contenu de tes données dans une variable Contenu.s, peut-être ainsi qu'un simple ReplaceString(Contenu,chr(avirer),chr(remplacant) suffirait.
Tu n'aurais plus qu'à réécrire le fichier propre.

Re: Petit problème : Trouver et remplacer un caractère NUL

Publié : jeu. 25/mars/2010 13:16
par case
c'est normal, un caractère nul indique la fin d'une chaine.

une solution serait de lire l'intégralité du fichier en mémoire et remplacer les 00 par des 32
puis de lire le nouveau fichier crée

Code : Tout sélectionner

file.s=OpenFileRequester("ouvrez un fichier","","*.*",1) ; selection du fichier
size=FileSize(file)                                      ; taille du fichier
*mem=AllocateMemory(size)                                ; reserve de la memoire pour charger le fichier
rd=ReadFile(#PB_Any,file)                                ; ouvre le fichier
If rd                                                    ; si le fichier est ouvert correctement
  ReadData(rd,*mem,size)                                 ; charge le fichier dans la memore alouée
  CloseFile(rd)                                          ;fermeture du fichier
  ;
  ; lecture de chaque octet en mémoire
  ;
  For offset=0 To size-1                                 ; taille -1 car on commence a zero au lieu de 1                            
    If PeekB(*mem+offset)=0                           ; si l'octet lu est 0
      PokeB(*mem+offset,32)                              ; on remplace par un espace
    EndIf
  Next
  wr=CreateFile(#PB_Any,GetPathPart(file)+"\clean_"+GetFilePart(file)) ; on cree un fichier pour sauvegarder la memoire
  If wr                                                                ; reussite
    WriteData(wr,*mem,size)                                            ;sauvegarde des données
    CloseFile(wr)                                                      ; fermeture du fichier
  EndIf
EndIf

Re: Petit problème : Trouver et remplacer un caractère NUL (

Publié : jeu. 25/mars/2010 21:07
par Malo
Merci à vous 2 pour avoir répondu aussi vite et en apportant tous les 2
une solution.

@Ar-s

Bien vu , pourtant j'aurais du trouver cette façon de faire car je l'avais déjà employé sur d'autres chaines.
Le principe fonctionne très bien.

Merci pour le lien sur le stockage des fichiers.

@Case

Ta méthode est intéressante car je vais pouvoir " apprendre les pointeurs
et les allocations mémoire "
Le principe fonctionne très bien.

Re: Petit problème : Trouver et remplacer un caractère NUL

Publié : jeu. 25/mars/2010 21:27
par case
tu peux aussi ne pas réécrire le fichier sur le disque et lire les lignes directement en mémoire.

cela nécessite un second buffer en mémoire et la réécriture des octets modifiés pour remplacer les retour ligne #crlf par des caractères null

Code : Tout sélectionner

file.s=OpenFileRequester("ouvrez un fichier","","*.*",1) ; selection du fichier
size=FileSize(file)                                      ; taille du fichier
*mem=AllocateMemory(size)                                ; reserve de la memoire pour charger le fichier
*mem2=AllocateMemory(size)                               ; reserve de la memoire pour les donées transformées
rd=ReadFile(#PB_Any,file)                                ; ouvre le fichier
If rd                                                    ; si le fichier est ouvert correctement
  ReadData(rd,*mem,size)                                 ; charge le fichier dans la memore alouée
  CloseFile(rd)                                          ;fermeture du fichier
  ;
  ; lecture de chaque octet en mémoire
  ;
  offset2=0                                              ; offset du buffer destination
  For offset=0 To size-1                                 ; taille -1 car on commence a zero au lieu de 1                            
    p=PeekB(*mem+offset)                                 ; on regarde la valeur en memoire
    Select p
      Case 0                                             ; si l'octet lu est 0
        PokeB(*mem2+offset2,32)                          ; on remplace par un espace
        offset2 +1                                       ; on avance dans le buffer destination
      Case 10                                            ;fin de ligne
        PokeB(*mem2+offset2,0)                           ; nul 
        offset2 +1                                       ; on avance dans le buffer destination
      Case 13                                            ; important de le metre quand même sinon on vas reecrire ce caractere en memoire
                                                         ; on ne fait rien et on avance pas dans le buffer destination
      Default                                            ; une autre valeur
        PokeB(*mem2+offset2,p)                           ; on ecrit la même valeur
        offset2 +1                                       ; on avance dans le buffer destination
    EndSelect            
  Next  
EndIf
 ; affichage des lignes
offset=0
Repeat
  st.s=PeekS(*mem2+offset)                                ;lecture en memeoire d'une chaine terminée par un caractere nul 
  Debug st                                                ; affichage de la ligne dans la fentre de debogage
  offset+Len(st)+1                                        ; on se place au debug de la ligne suivant
Until offset>=offset2                                     ; on recommence tant qu'on est pas a la fin ;)

FreeMemory(*mem)
FreeMemory(*mem2)

End

Re: Petit problème : Trouver et remplacer un caractère NUL

Publié : ven. 26/mars/2010 1:22
par Malo
merci Case pour cette solution plus élaborée, je vais regardé ça avec attention
pour bien comprendre la "gymnastique" des pointeurs et l'adressage mémoire