ReplaceString

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
LOULOU25
Messages : 150
Inscription : mer. 19/mai/2004 20:40

ReplaceString

Message par LOULOU25 »

La fonction ReplaceString bugge avec le mesage suivant sur les variables déclarés de plus de 64 K° :
Stack Overflow. Can occur during errant recursion or when a function creates a particular large array on the stack

Quelq'un connait-il la solution à ce problême ou une solution analogue ?

Code : Tout sélectionner

 Procedure ManipulationBufferSize(Bytes) 
  PBStringBase.l = 0 
  PBMemoryBase.l = 0 
  !MOV Eax, dword [PB_StringBase] 
  !MOV [Esp+4],Eax 
  !MOV Eax, dword [PB_MemoryBase] 
  !MOV [Esp+8],Eax 
  HeapReAlloc_(PBMemoryBase, #GMEM_ZEROINIT, PBStringBase, Bytes) 
  !MOV dword [_PB_StringBase],Eax 
EndProcedure 
OnErrorGoto(?fin)


ManipulationBufferSize(1084576) 

calldebugger
toto.s= "BONJOUR"+space(500000)+"XY"

toto= ReplaceString(toto,"BO","AC",1,1)


Debug Left(toto,8)

Fin:
Debug GetErrorDescription() 
Heis Spiter
Messages : 1092
Inscription : mer. 28/janv./2004 16:22
Localisation : 76
Contact :

Message par Heis Spiter »

Essaie avec la Lib LargeString de cederavic http://www.serveurperso.com/~cederavic/mecrea.htm
Heis Spiter, webmaster du site http://www.heisspiter.net
Développeur principal et administrateur du projet Bird Chat
Parti courir au bonheur du dév. public et GPL :D
fweil
Messages : 505
Inscription : dim. 16/mai/2004 17:50
Localisation : Bayonne (64)
Contact :

Message par fweil »

LOULOU25,

Bien qu'il ne soit pas interdit de modifier l'allocation dynamique pour la déclaration de chaines de + de 64K, les fonctions proposées par PureBasic sont quant à elles réalisées et spécifiées avec cette limite de 64K. Ce qui fait qu'il n'est pas possible de les utiliser avec une allocation non standard.

Par contre rien n'interdit de ré-écrire quelques fonctions comme Mid, Left, Right, Ucase, Lcase, FindString et ReplaceString ...

Je vais m'y pencher de mon côté pour me faire une petite récré, mais si qq'un d'autre veut également y travailler, on peut se partager le boulot ...

Le principe est simple à mon avis, consistant à faire de l'analyse de tableau d'octets une fois déclarée la chaine longue.

Slts
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.
LOULOU25
Messages : 150
Inscription : mer. 19/mai/2004 20:40

Message par LOULOU25 »

Heis Spiter a écrit :Essaie avec la Lib LargeString de cederavic http://www.serveurperso.com/~cederavic/mecrea.htm
Cette bibliothéque ne fonctionne pas sur les chaines de + de 64 K°, je l'ais déjà essayé.
LOULOU25
Messages : 150
Inscription : mer. 19/mai/2004 20:40

Message par LOULOU25 »

LOULOU25 a écrit :,Fveill

Voici un bout de code qui fonctionne sur un remplacement global dans une chaine mais qui est extrémement lent. N'ayant pas les compétences requises pour aller plus loin dans le code peut-être celà t'aidera-til a gagner du temps et à sortir une possibilité plus rapide en temps d'execution

Code : Tout sélectionner

  Procedure.l ReplaceFileData(FileName.s,  *searchdata.l, searchdataLen.l, *replacedata, replacedataLen.l) 
    Protected templ.l 
    Protected *tempmem.l 
    Protected fileLen.l 
    Protected numResults.l 
    Protected searchdataLen.l
    Protected replacedataLen.l
    Protected j
    Protected i 
    
    
    fileLen = FileSize(FileName)  
    If fileLen < 1 Or searchdataLen < 1 
      ProcedureReturn -1 
    EndIf 
    
    If OpenFile(0, FileName) 
      *tempmem = AllocateMemory(fileLen) 
      ReadData(*tempmem, fileLen) 
      CloseFile(0) 
     
      If CreateFile(0, FileName) 
        i = 0 
        While i <= fileLen - 1 
          If PeekB(*tempmem + i) <> PeekB(*searchdata) 
            WriteByte(PeekB(*tempmem + i)) 
            i + 1 
          Else 
            same = #True : j=1 
            While same = #True And j < searchdataLen 
              If PeekB(*tempmem + i + j) <> PeekB(*searchdata + j) 
                same = #False 
              Else 
                j+1 
              EndIf 
            Wend 
            If same = #True 
              WriteData(*replacedata, replacedataLen) 
              numResults + 1 
            Else 
            WriteData(*tempmem + i, j) 
            EndIf 
            i + j 
          EndIf 
        Wend 
       CloseFile(0) 
       FreeMemory(*tempmem)
    Else 
      ProcedureReturn -3 
      EndIf 
      
    Else 
      ProcedureReturn -2 
    EndIf 
    
    ProcedureReturn numResults 
  EndProcedure

;Invocation de la procédure 
 searchstring.s="#=" + Trim(code_societe)  ; This is the text to look for
      replacestring.s="#=" + Trim(Nom_societe) ; Replace every found occurence of the above string with this string
      Length=Len(searchstring) 
      Lenght1 = Len(replacestring)   
      ReplaceFileData(strChemin,@searchstring,Length,@replacestring,Lenght1)




[/code]
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

j'ai écrit une procédure permettant de remplacer une chaine par une autre quelque soit la taille du fichier.

Cette procédure permet aussi de faire plusieurs remplacement de chaines en une seule passe.

Voir site Code FR - > Fichiers et Dossiers -> Lecture / écriture de fichier -> Remplacer une chaine


http://perso.wanadoo.fr/lesoldatinconnu/CodesFR

:)
LOULOU25
Messages : 150
Inscription : mer. 19/mai/2004 20:40

Message par LOULOU25 »

nico a écrit :j'ai écrit une procédure permettant de remplacer une chaine par une autre quelque soit la taille du fichier.
Merci Nico ta procédure marche à merveille et rapidement
fweil
Messages : 505
Inscription : dim. 16/mai/2004 17:50
Localisation : Bayonne (64)
Contact :

Message par fweil »

Bon pour la forme, je poste la suite sur Trucs et Astuces
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.
Avatar de l’utilisateur
ZapMan
Messages : 460
Inscription : ven. 13/févr./2004 23:14
Localisation : France
Contact :

Message par ZapMan »

Code : Tout sélectionner

;************************************************************
;* Le truc de Fred pour augmenter la taille du buffer texte *
;*   et éviter les plantage quand on manipule des grandes   *
;*    chaines de caractères.                                *
;************************************************************

Procedure SetStringManipulationBufferSize(Bytes)
  PBStringBase.l = 0
  PBMemoryBase.l = 0
  !MOV eax, dword [PB_StringBase]
  !MOV [esp+4],eax
  !MOV eax, dword [PB_MemoryBase]
  !MOV [esp+8],eax
  HeapReAlloc_(PBMemoryBase, #GMEM_ZEROINIT, PBStringBase, Bytes)
  !MOV dword [_PB_StringBase],eax
EndProcedure

; Set the buffer size for all strings to 1 MB.

SetStringManipulationBufferSize(1000000)
Avec ça, j'utilise toutes les fonctions de PB sur des textes de plus de 64ko (et je fais ça tous les jours !!)
Tout obstacle est un point d'appui potentiel.

Bibliothèques PureBasic et autres codes à télécharger :https://www.editions-humanis.com/downlo ... ads_FR.htm
fweil
Messages : 505
Inscription : dim. 16/mai/2004 17:50
Localisation : Bayonne (64)
Contact :

Message par fweil »

ZapMan,

Heuu : un affreux doute ? J'aurai pu avoir cet affreux doute + tôt !

Autant que je m'en souvienne le changement d'allocation dynamique il y a quelques mois n'avait pas d'effet sur les fonctions comme FindString etc ... mais maintenant si !

Donc tu as raison et merci, cela m'évitera de me prendre la tête plus sur ce point.

FindString et le reste fonctionne apparement sur des chaines longues si on utilise la procédure de changement de taille max et que l'on ne remet la valeur par défaut tout de suite derrière.

Dans le cas de traitement d'un fichier chargé d'un seul bloc dans un buffer, il suffit de faire par exemple un FindString(Peeks(*Buffer), Cherche, 1)) et c'est tout bon.

Et les performances suivent en conséquence.

Donc je laisse mes réflexions ci-dessus pour le temple de la honte et je travaille désormais avec cette idée en tête. Tout va bien en changeant simplement la taille max.

Slts
Mon avatar reproduit l'image de 4x1.8m présentée au 'Salon international du meuble de Paris' en janvier 2004, dans l'exposition 'Shades' réunisant 22 créateurs autour de Matt Sindall. L'original est un stratifié en 150 dpi.
LOULOU25
Messages : 150
Inscription : mer. 19/mai/2004 20:40

ReplaceString

Message par LOULOU25 »

Fveil,
Voici un bout de code qui te démontre le problême constaté sur les chaines de plus de 64 K° sachant effectivement que le problême ne se produit pas avec la fonction FINDSTRING mais seulement avec REPLACESTRING qui génére un "stack overflow" .
Logiquement tu devrais avoir un message d'erreur.

Code : Tout sélectionner

OnErrorGoto(?erreur)

  Procedure SetStringManipulationBufferSize(Bytes) 
  PBStringBase.l = 0 
  PBMemoryBase.l = 0 
  !MOV eax, dword [PB_StringBase] 
  !MOV [esp+4],eax 
  !MOV eax, dword [PB_MemoryBase] 
  !MOV [esp+8],eax 
  HeapReAlloc_(PBMemoryBase, #GMEM_ZEROINIT, PBStringBase, Bytes) 
  !MOV dword [_PB_StringBase],eax 
EndProcedure 
  
SetStringManipulationBufferSize(100012) 
CallDebugger

Toto.s = "BONJOUR" + Space(100000)+"ABCD"
Toto = ReplaceString(Toto,"ABCD","CDEFG",1,1)
Debug Right(toto,4)

Erreur:
Debug GetErrorDescription() 
Pour Zapman merci de m'envoyer le cas échéant un bout de programme qui fonctionne avec replacestring. Il s'agit peut-être d'une erreur de programmation de ma part.
Avatar de l’utilisateur
ZapMan
Messages : 460
Inscription : ven. 13/févr./2004 23:14
Localisation : France
Contact :

Message par ZapMan »

Mea Maxima Culpa

Il est vrai que je n'utilise pas TOUTES les fonctions texte de PB. En parcourant mes codes, je mes suis apperçu qu'en fait, je n'utilise jamais ReplaceString, ce qui explique que je n'avais pas constaté le bug de cette fonction. Je te promets par contre que je n'ai vraiment aucun souci avec left, right, len et findstring. Voici un code qui marche :

Code : Tout sélectionner

OnErrorGoto(?erreur) 

Procedure SetStringManipulationBufferSize(Bytes) 
  PBStringBase.l = 0 
  PBMemoryBase.l = 0 
  !MOV eax, dword [PB_StringBase] 
  !MOV [esp+4],eax 
  !MOV eax, dword [PB_MemoryBase] 
  !MOV [esp+8],eax 
  HeapReAlloc_(PBMemoryBase, #GMEM_ZEROINIT, PBStringBase, Bytes) 
  !MOV dword [_PB_StringBase],eax 
EndProcedure 
  
SetStringManipulationBufferSize(100012) 

Toto.s = "BONJOUR" + Space(100000)+"ABCD" 

;fs = ReplaceString(Toto,"ABCD","CDEFG",1,1)

        fs = FindString(Toto,"ABCD",1) 
        If fs
          Repeat 
            Toto=Left(Toto,fs-1)+"CDEFG"+Right(Toto,Len(Toto)-fs-Len("ABCD"))
            fs = FindString(Toto,"ABCD",1) 
          Until fs = 0
        EndIf 
 
Debug Right(toto,4) 

Erreur: 
Debug GetErrorDescription()
Tout obstacle est un point d'appui potentiel.

Bibliothèques PureBasic et autres codes à télécharger :https://www.editions-humanis.com/downlo ... ads_FR.htm
Répondre