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

C++Builder Discussion :

Valeur Ascii d'un AnsiString


Sujet :

C++Builder

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mai 2002
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 39
    Points : 34
    Points
    34
    Par défaut Valeur Ascii d'un AnsiString
    Salut à tous,

    je dois faire un algorythme qui lit un fichier texte et l'insére dans une base de données.

    Les champs sont séparés par une tabulation.

    Seulement, je n'arrive pas à trouver les méthode dans C++ Builder qui me permettraient de travailler sur la valeur Ascii d'un caractère.

    Si quelq'un pouvait m'indiquer ...

    j'ai cherché sur le forum et via google mais, rien trouvé.

    Tous mes champs sont déclarés Ansistring

    Voici mon 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
     
    //---------------------------------------------------------------------------
    AnsiString __fastcall TForm_CDR::GetStringFromCDR(AnsiString *Data, int *Position)
    {
     AnsiString Field;
     while ((Data->SubString(*Position,1) < 32)) //boucle qui  concaténe jusqu'a l'arrivé de la tabulation..
     {
            Field = Field + Data->SubString(*Position,1);
            *Position = *Position + 1;
            ShowMessage(IntToStr(Data->SubString(*Position,1).Length()));
     }
     while ((Data->SubString(*Position,1) == 9) ) //fonction qui nous renvoie après le prochain éspace
     {
         if (Data->SubString(*Position,1) < 33)
            *Position = *Position + 1;
     }
     return Field;
    }
    //---------------------------------------------------------------------------
    ce code n'est évidement plus très bon, j'ai dèjà fait beaucoup de test.

    Merci.

  2. #2
    Membre chevronné
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Points : 1 911
    Points
    1 911
    Par défaut
    Hum... Ça sent l'exo, on n'aime pas trop ici, mais bon vous avez fait un effort et tentant du code.

    Il n'est pas très bon d'utiliser un pointeur vers un AnsiString ni vers un entier. Comme Position doit être renvoyé à l'appelant, utilisez le signe & propore au C++. Si A est un AnsiString, A[i] est le ième catactère avec i commençant à 1. De plus, la tabulation est très fréquemment remplacée par une série d'espaces, donc il faut peut-être mieux tester le caractère espace, ascii=32. Voici comment on pourrait procéder. Vous déclarez la fonction.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AnsiString __fastcall GetStringFromCDR(AnsiString,int&);
    Vous faites un jeu de test pour vérifier sur trois champs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    const AnsiString A="    toto   tutu  tata     ";
    int i,p=1;
    AnsiString C;
    for(i=0;i<3;i++)
    C=GetStringFromCDR(A,p);
    Et vous écrivez la fonction.

    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
    AnsiString __fastcall TForm1::GetStringFromCDR(AnsiString Data, int &Position)
    {
     AnsiString Field;
     int fin=Data.Length();
     char c;
     bool ok=true;
     
     Data+=" ";
     while(ok && Position!=fin) ok=(Data[Position++]==32);
     
     Position--;
     ok=true;
       while(ok && Position!=fin)
          {
          if((c=Data[Position++])==32) ok=false;
          if(ok) Field+=c;
          }
     return Field;
    }
    Je rajoute un espace à la fin de la chaîne pour être sûr de ne jamais sortir avec un indice supérieur au nombre de caractères, c'est une sorte de délimiteur final. Sinon utilisez les syntaxes C++ notamment i++ pour incrémenter, += pour ajouter et ainsi de suite. Après avoir sauté la série d'espaces précédant le champ à renvoyer, Position a été incrémenté une fois de trop d'où sa décrémentation pour pointer le premier caractère du champ (Position--). Bien entendu, ce genre d'algorithme suppose qu'il y ait vraiment un champ, si un champ est vide, le nième champ passera pour le n-1ième et tout sera décalé.

    À bientôt
    Gilles

  3. #3
    Nouveau membre du Club
    Inscrit en
    Mai 2002
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 39
    Points : 34
    Points
    34
    Par défaut
    en fait, si j'ai bien compris,

    la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    AnsiString __fastcall GetStringFromCDR(AnsiString,int&);
    attend l'adresse d'un entier.

    et lors de l'appel, je dois juste passer l'entier. C++ Builder fait les cnversions lui-même.

    Désolé, mais j'étais un peu dérouté.
    Dans mon livre C++ ils parlent des pointeurs, mais dans c++ Builder l'utilisation n'est pas toujours identique.

    La règle est donc de ne pas déclarer de pointeur vers des variable telles que Entier, Chaines, Réél ?. par contre de passer leur adresse dans certaine fonctions ?

    En fait, je voulais juste déclarer un Ansistring et passer son adresse pour que d'autres fonctions puisse travailler sur cette variable sans devoir au préalable la dupliquer. (qui est, je pense une bonne idée au départ).

    Merci beaucoup.

    Ps : je vais jetter un oeil sur les tutos C++ Builder.

  4. #4
    Nouveau membre du Club
    Inscrit en
    Mai 2002
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 39
    Points : 34
    Points
    34
    Par défaut
    Encore une petite question

    Vous me dites
    De plus, la tabulation est très fréquemment remplacée par une série d'espaces, donc il faut peut-être mieux tester le caractère espace, ascii=32.
    Mais quand je fais le test suivant à l'endroit de la tabulation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ShowMessage("-"+Data.SubStr(1,1)+"-"); //Pour bien voir le nombre d'espace
    le showMessage me renvoie plusieurs caractères d"espace alors que je n'ai copié" que sur 1 caractère dans la fonction "SubStr"

  5. #5
    Membre chevronné
    Avatar de Gilles Louïse
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    421
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2002
    Messages : 421
    Points : 1 911
    Points
    1 911
    Par défaut
    Je ne vois pas trop ce que vous voulez dire par votre question, simplement l'expérience montre que la tabulation est souvent remplacée dans les fichiers texte par plusieurs espaces. L'algorithme que je vous ai donné est bon mais il suppose que le fichier est correctement renseigné. En principe, on préfère structurer les fichiers en formatant chaque champ, par exemple 5 caractères pour le premier champ, 18 pour le second et ainsi de suite. Ainsi, si un champ est vide, cela ne décalera pas le reste de la ligne. Alors qu'en délimitant par un ou plusieurs espaces, l'absence d'un champ décalera tout le reste.

    À bientôt
    Gilles

  6. #6
    Nouveau membre du Club
    Inscrit en
    Mai 2002
    Messages
    39
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 39
    Points : 34
    Points
    34
    Par défaut
    Merci de votre aide,

    malheureusement le format m'est imposé par le fournisseur du fichier.

    l'algorithme fonctionne à présent.

    pour palier à ce contrôle d'erreur et éviter tout décalage,
    avant d'inserer les lignes dans la DB je vérifie le nombre de champs et en cas dérreur je fais un roolback et signale à l'utilisateur (qui seras averti) le numéro de ligne qui pose problème.

    bonne journée.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comparaison de lettres avec valeur ASCII
    Par Vince dans le forum C++
    Réponses: 4
    Dernier message: 04/03/2009, 11h20
  2. Valeur ASCII d'une chaine, fct atoi() ?
    Par Freud44 dans le forum C++
    Réponses: 7
    Dernier message: 23/02/2009, 16h18
  3. ECX en valeur ASCII
    Par helmont dans le forum x86 32-bits / 64-bits
    Réponses: 3
    Dernier message: 08/12/2007, 18h10
  4. Comment récuperer la valeur ASCII d'un caractère ?
    Par El-Diablo- dans le forum C++Builder
    Réponses: 9
    Dernier message: 05/03/2007, 18h11
  5. Réponses: 25
    Dernier message: 08/03/2006, 17h03

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