IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Initiale sur une chaine


Sujet :

Langage Delphi

  1. #1
    Inactif  
    Inscrit en
    Février 2004
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 97
    Points : 53
    Points
    53
    Par défaut Initiale sur une chaine
    Je suis surpris par le comportement du traitement du premier caractère d'une chaine. (Je travaille sur un prog. qui traite une grande liste de mots : 430 000)

    sans changer quoi que ce soit d'autre que la ligne incriminée :
    ce programme fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Var
    ..
    L3 : array[1..100] of String[13];
     
    F : TextFile;
    Lignelue :String[13];
     
    ...
    // ce code fonctionne
    Begin
    Readln (F, Lignelue);
      L3[j]:= Lignelue;
     
      While ((Copy(Lignelue,1,1)='+') OR (Copy(Lignelue,1,1)=' '))do
    et celui-ci m'envoie un "violation access"... (peut-être après avoir affiché environ 32000 lignes - je ne peux vérifier)
    // ce code me renvoie une erreur
    // échec du projet F:\Delphi.... Pr1.exe avec le message : 'access violation ...'

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Var
    ..
    L3 : array[1..100] of String[13];
    L4 : String[13];
    F : TextFile;
    Lignelue :String[13];
     
     
    Begin
     
    Readln (F, Lignelue);
     L3[j]:= Lignelue;L4:=Lignelue;
     While((L4[1]='+') OR (L4[1]=' ')) do
    Si quelqu'un peut m'éclairer, merci ...

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 671
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 671
    Points : 25 481
    Points
    25 481
    Par défaut
    rassure moi j ne monte pas à 32000 ?

  3. #3
    Inactif  
    Inscrit en
    Février 2004
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 97
    Points : 53
    Points
    53
    Par défaut
    Non, non, bien sûr !
    J compte de petites variations.

    D'ailleurs ça n'intervient pas dans l'écriture de la ligne qui cherche l'initiale de la chaîne.

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 213
    Points : 41 477
    Points
    41 477
    Billets dans le blog
    63
    Par défaut
    bonjour,
    et le cas ou la chaine est nulle ? il est traité ?

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 671
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 671
    Points : 25 481
    Points
    25 481
    Par défaut
    Avec des String[13] cela ne devrait pas poser problème
    Tu ne dépasse jamais d'index dans L4 ?

    Comme ça se passe si ReadLn veut lire plus que 13 caractères et qu'on lui passe une ShortString de 13 caractères ?

    En partant de la remarque de SergioMaster :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Var
    ..
    L3 : array[1..100] of String[13];
     
    F : TextFile;
    Lignelue :String; // Non limité !
     
    ...
    // ce code fonctionne
    Begin
    Readln (F, Lignelue);
      L3[j]:= Lignelue; // Troncature 
     
    While (Length(Lignelue) >= 1 ) and ((Lignelue[1]='+') OR (Lignelue[1]=' ')) do

  6. #6
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Points : 757
    Points
    757
    Par défaut
    tu devrais mettre un point d'arrêt sur la ligne "Readln (F, Lignelue);", puis faire du pas à pas pour savoir où ça plante exactement, et au passage mettre "L3[j]:= Lignelue;L4:=Lignelue;" sur deux lignes séparées, si jamais l'erreur vient d'une de ces deux affectations...
    Ensuite on pourra te donner nos avis "plus avisés".

  7. #7
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 494
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 494
    Points : 3 129
    Points
    3 129
    Par défaut
    et une variable incrémentée à chaque tour ?
    un bon try except et dans le déclenchement de l'exception, on affiche le numéro de ligne et même sa valeur

  8. #8
    Membre éclairé Avatar de peter27x
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 029
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 029
    Points : 757
    Points
    757
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    et une variable incrémentée à chaque tour ?
    un bon try except et dans le déclenchement de l'exception, on affiche le numéro de ligne et même sa valeur
    Oui mais il aura comme seule info le n-ième tour où arrive l'erreur mais rien sur la ligne de code l'ayant généré hélas !
    Le mieux serait alors peut être un try except autour de chacune des lignes de code, vu qu'il n'y en pas beaucoup qu'il soupçonne de générer l'erreur (je me base sur le fait qu'il nous a donné que quelques lignes de codes bien précises dans son sujet).
    Ou alors il écrit dans un bon vieux fichier LOG...

  9. #9
    Inactif  
    Inscrit en
    Février 2004
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 97
    Points : 53
    Points
    53
    Par défaut
    Je vois que plusieurs intervenants se sont penchés sur mon bout de programme.
    MERCI.
    Au vu du code, vous allez tout de suite deviner que je suis loin d'être fortiche ...
    Variante : J'ai essayé de faire tourner ça avec TstringList.

    Ma question se situait pour la variante de la ligne 81 du code ci-dessous.
    Mais elle entraîne sans doute d'autres interrogations.


    Voici ce que je veux faire :
    traiter une liste de mots (un peu plus de 400 000) dans un fichier qui a la structure suivante :
    (sans les commentaires que j'ai ajoutés)

    .../...
    AAABBMS
    +R BAMBARAS
    AAABBRS
    +M BAMBARAS
    AAABCEN
    +N ENCABANA
    +R CABANERA (2 + de suite)
    AAABCCI
    CACABAI (1 sec + 3 avec 1 lettre de plus)
    +L ACCABLAI
    +S CACABAIS
    +T CACABAIT
    AAABCCL
    ACCABLA
    +I ACCABLAI
    +M CALAMBAC
    +S ACCABLAS
    +T ACCABLAT
    AAABCCM
    +L CALAMBAC
    AAABCCN
    +T CACABANT
    AAABCCR
    BACCARA
    +E CACABERA
    +S BACCARAS
    +T BACCARAT
    .../...

    En langage scrabble on appelle ça 7+ 1.
    Mon but : extraire, par exemple, toutes les séries de 4 anagrammes possibles soit 7 lettres soit avec une lettre de plus.
    (exemple : BACCARA +E donne CACABERA ... du verbe cacaber !)
    Le bout de code suivant fonctionne MAIS il ne repère pas quand la première ligne débute par 3 espaces (scrabble sec).
    (Ligne 69)

    Il n'y a jamais de chaines vides.

    CODE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    var
      Form1: TForm1;
      InputString,NbTir : String; //pour nom fichier txt
     
      RES : TResourceStream;
       F : TextFile;
      lignelue, L1,L2,L3, L4 : string[13];
      //Memligne : array[1..430400] of String[13];
      Flag : Integer;
     
    implementation
     
    {$R *.DFM}
    {$R 7plus1.RES}
     
    PROCEDURE RESSOURCE;
    Var
            FileStream : TFileStream;
     
    Begin
      Res:= TResourceStream.Create(Hinstance,'RES_plus1',RT_RCDATA);
      TRY
      FileStream:=TFileStream.Create('7plus1.txt',fmcreate);
         TRY
         FileStream.CopyFrom(RES,0);
         Finally
         FileStream.Free;
         End;
      Finally
      RES.Free;
      End;
       end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    Var
     j,nb_anag, k, nombre_tirage :LongWord;
     L3 : array[1..100] of String[13];
     L4 : String[13];
     
    begin
       Flag:=1;// pour nom du fichier (bouton 1)
     
    Repeat
        InputString:= InputBox('CHERCHE 7 + 1', 'Combien d''anagrammes ? (Entre 1 et 30 maxi) ', '?');
               If InputString='?' then halt; // bouton annuler
        nb_anag:=StrToInt(InputString);
    Until nb_anag in [1..30];
     
          RESSOURCE;
     
     j:=0; nombre_tirage:=0;
     
    ListBox1.clear;
    Listbox1.Sorted:=FALSE;
     
    AssignFile(F,'7plus1.txt'); // 
     
    Reset(F);
     
     
    While not eof(F) do
    Begin
      Readln(F,lignelue);
        L1:=lignelue ;
     
     If L1[1] in ['A'..'R'] then   // il n'y a pas de chaine après R donc je ne vais pas jusqu'à Z
      Begin
       Readln(F,lignelue); L2:=Lignelue;
          If  Copy(L2,1,1)='+'  then       // FONCTIONNE s'il n'y a pas de scrabble "sec" à 7 Lettres avant
     
         //  If (L2[1]='+') or (L2[1]=' ') then                    // non Je ne peux tester que sur '+'  !
        //   If  (Copy(L2,1,1)='+') OR (Copy(L2,1,1)=' ') then   // non ne fonctionne pas non plus   !
     
        Begin
          Readln(F,lignelue);
     
          inc(j); L3[j]:= Lignelue; L4:=Lignelue;   // L4 pour essai seulement  
     
      While ((Copy(Lignelue,1,1)='+') OR (Copy(Lignelue,1,1)=' '))do
     
         //   While((L4[1]='+') OR (L4[1]=' ')) do    // non - c'est ma question!
     
            Begin
              inc(j);
              Readln(F,lignelue);
              L3[j]:=Lignelue;
     
      End; // de while N°2
     
            If (j=nb_anag) then
              Begin
                ListBox1.Items.Add(L1); // le tirage
                ListBox1.Items.Add(L2); // la soluce 1
     
     
                If (nb_anag>1) and (j>0) then
                  Begin
                   For k :=1 to j-1 do  ListBox1.Items.Add(L3[k]); // soluces suivantes
     
                     ListBox1.Items.Add('');  // saut ligne
                  End;
              End;
     
        End;
     
        j:=0 ;
     
        End;
    End;
    Label1.Visible:=TRUE;
    Label4.Visible:=TRUE;
    Button3.Visible:=True; // permet l'enregistrement du ListBox
    nbTir:= IntToStr(nombre_tirage);
    Label4.Caption:=' Nombre de tirages : '+ nbTir;
    CloseFile(F);
     
    end;// de la procedure
    Merci pour vos éclairages et indications éventuelles pour traquer le "violation access" !

  10. #10
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 213
    Points : 41 477
    Points
    41 477
    Billets dans le blog
    63
    Par défaut
    j'ai jetté un coup d’œil rapide sur le source , pour le while numero 2 le EOF n'est pas traité ?
    en fait j'ai du mal a comprendre la logique sous-jacente , mais comme dit plus haut je n'ai que jeté un œil pas les 2

  11. #11
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    bon, voir mes commentaires entre (* et *)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
     
    var
      Form1: TForm1;
     
    (*
      Pourquoi des variables globales ?!
      soit le code est lié à Form1 puisque lancé dans Button1Click
      soit il en est indépendant, et on colle tout cela dans une nouvelle unité Scrable
    *)
      InputString,NbTir : String; //pour nom fichier txt
     
      RES : TResourceStream;
       F : TextFile;
      lignelue, L1,L2,L3, L4 : string[13];
      //Memligne : array[1..430400] of String[13];
      Flag : Integer;
     
    implementation
     
    {$R *.DFM}
    {$R 7plus1.RES}
     
    (* ça c'est très très moche, j'utiliserais plutôt TStringList.LoadFromStream() sur un ResourceStream *)
    procedure RESSOURCE;
    var
      FileStream : TFileStream;
    begin
      Res:= TResourceStream.Create(Hinstance,'RES_plus1',RT_RCDATA);
      try
        FileStream := TFileStream.Create('7plus1.txt', fmCreate);
        try
          FileStream.CopyFrom(RES,0);
        finally
          FileStream.Free;
        end;
      finally
        RES.Free;
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    Var
     j,nb_anag, k, nombre_tirage :LongWord;
     L3 : array[1..100] of String[13];
     L4 : String[13];
     
    begin
      Flag:=1;// pour nom du fichier (bouton 1)
     
      repeat
        InputString:= InputBox('CHERCHE 7 + 1', 'Combien d''anagrammes ? (Entre 1 et 30 maxi) ', '?');
        If InputString='?' then halt; // bouton annuler
        nb_anag:=StrToInt(InputString);
      until nb_anag in [1..30];
     
      RESSOURCE;
     
      j:=0;
      nombre_tirage:=0;
     
      ListBox1.clear;
      Listbox1.Sorted:=FALSE;
     
      AssignFile(F,'7plus1.txt'); //
     
      Reset(F);
     
     
      While not eof(F) do
      Begin
        Readln(F,lignelue); (* exemple : AAABBMS *)
        L1:=lignelue ;
     
        If L1[1] in ['A'..'R'] then   // il n'y a pas de chaine après R donc je ne vais pas jusqu'à Z
        Begin
          Readln(F,lignelue); L2:=Lignelue; (* exemple: +R BAMBARAS *)
     
         (* un String[13] possède toujours un élément 1, mais si la chaîne est vide c'est l'élément 1 de la précédente chaîne lue qui n'a pas été effacé ! *)
          if (L2 <> '') and (L2[1] = '+') then
          Begin
            Readln(F,lignelue); (* exemple: AAABBRS - POURQUOI ?! *)
     
            inc(j);
            L3[j]:= Lignelue;
            L4:=Lignelue;   // L4 pour essai seulement
     
            while (L4 <> '') and ((L4[1] = +) do
            Begin
              inc(j);
              Readln(F,lignelue);
              L3[j]:=Lignelue;
     
            End; // de while N°2
     
            If (j=nb_anag) then
            Begin
              ListBox1.Items.Add(L1); // le tirage
              ListBox1.Items.Add(L2); // la soluce 1
     
     
              If (nb_anag>1) and (j>0) then
              Begin
                For k :=1 to j-1 do  ListBox1.Items.Add(L3[k]); // soluces suivantes
                  ListBox1.Items.Add('');  // saut ligne
              End;
            End;
     
          End;
     
          j:=0 ;
     
        End;
      End;
      Label1.Visible:=TRUE;
      Label4.Visible:=TRUE;
      Button3.Visible:=True; // permet l'enregistrement du ListBox
      nbTir:= IntToStr(nombre_tirage);
      Label4.Caption:=' Nombre de tirages : '+ nbTir;
      CloseFile(F);
     
    end;// de la procedure

  12. #12
    Inactif  
    Inscrit en
    Février 2004
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 97
    Points : 53
    Points
    53
    Par défaut
    Merci à P.Thot pour avoir sans doute passé du temps sur mon (affreux) programme.

    Je digère ses commentaires et je mets une réponse dès que je peux.

    Pour l'utilisation préférable de StringList : OK. J'avais déjà essayé.

    Je m'y colle.

    MERCI !

  13. #13
    Inactif  
    Inscrit en
    Février 2004
    Messages
    97
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 97
    Points : 53
    Points
    53
    Par défaut
    Commentaires des commentaires de Thot.

    Ok pour l'histoire des var mal placées et pour le Stringlist que je vais utiliser.

    Chaine de String[13] : dans ma liste elles ne sont jamais vides. Tous les mots sont mis les uns à la suite des autres.

    Ensuite : le "pourquoi ?!" ....je ne pige pas.
    Si la lecture de ma 2eme ligne ne commence ni par un espace (peut-être mal visible dans le listing (c'est ' ' et non ''), ni par par un (+) alors je veux lire les lignes suivantes pour extraire par groupes de longueur déterminée (2,3 4 etc...) toutes les anagrammes possibles.
    Mon prog est certainement mal foutu; il est tard; la nuit va me porter conseil !
    Pour info j'ai 94044 chaines qui commencent par une lettre majuscule (DE A jusqu'à R), 224447 qui commencent par + et 111893 par un espace.

Discussions similaires

  1. [VBA-E] test sur une chaine de charactère
    Par gruget dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 10/04/2006, 14h24
  2. fread sur une chaine de caractere ?
    Par Battosaiii dans le forum C
    Réponses: 17
    Dernier message: 18/03/2006, 12h50
  3. Masque sur une chaine
    Par Weedo dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 10/01/2006, 11h32
  4. Erreur de segmentation sur une chaine en récursif...
    Par laurent_ifips dans le forum C
    Réponses: 12
    Dernier message: 13/12/2005, 16h04
  5. [Débutant][String] Opérations sur une chaîne
    Par gandalf_le_blanc dans le forum Général Java
    Réponses: 8
    Dernier message: 08/06/2004, 11h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo