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 :

copie d'un fichier non txt dans String pour envoie rs232


Sujet :

C++Builder

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut copie d'un fichier non txt dans String pour envoie rs232
    Bonjour à tous,

    J'ai lu et relu les FAQ's sans trouver mon bonheur, je souhaite copier le contenue d'un fichier, en paramètre, dans une AnsiString, le problème que j'ai rencontrer est que, dans certain de mes fichiers se trouve des caractères ASCII correspondant à des EOF, ce qui provoque l’arrêt de la lecture de mon fichier, D'où mon code suivant

    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
     
    AnsiString read_file(std::ifstream &file_to_send)
    {
     
            AnsiString Trame;
            U32 nb=nb_byte_file(file_to_send);
            U32 tailleTrame = Trame.Length();
     
            while(tailleTrame<nb)
            {
                    char * ligne_lue = new char[nb];
     
                    file_to_send.read(ligne_lue,nb);
     
                    Trame+=ligne_lue;
                    ShowMessage(Trame);
     
                    tailleTrame = Trame.Length();
                    file_to_send.seekg(tailleTrame+1,ios::beg);
     
                    delete[] ligne_lue;
                    ShowMessage(tailleTrame);
            }
            return Trame;
    }
    Ce code fonctionne très bien pour des fichiers txt mais pas pour des fichiers jpg, et fnt. Si quelqu'un à déjà eu ce genre de problème, ou connait une solution je suis preneur,
    merci d'avance.

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    file_to_send est ouvert en mode ios::binary ?

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    oui

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    file_to_send.open(name_file,ios::binary);

  4. #4
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    Est-ce que tu as vérifié que ça ne marchait pas, en affichant les lignes avant de les rentrer dans Trame, par exemple ?

    Normalement, la lecture d'un fichier ne s'arrête pas au caractère EOF. (qui, d'ailleurs, n'existe pas : https://duckduckgo.com/?q=ascii+table )

    Par contre, si tu as un NUL ('\0'), ça va bloque ton char * ; qui ne va pas réussir à savoir où s'achève la chaîne de caractère (même si tu peux récupérer cette information avec file_to_send.gcount()).

    Du coup, àmha, ton problème ne vient pas de la lecture du fichier, mais plutôt du remplissage de l'AnsiString.

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    oui oui j'ai vérifié que ça ne fonctionnait pas, en mettant des ShowMessage(ligne_lue) après file_to_send.read(ligne_lue,nb) et j'ai remarqué que le caractère sur lequel il s’arrêtait était le caractère 0x03 ou ETX(pour moi c'est un EOF )
    Le problème viens bien de la lecture a mon avis car l'affichage de la ligne_lue ne me donne pas ce que je veux.

  6. #6
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    Le caractère suivant le 0x03 n'est pas un 0x00 ?

    Parce que, en théorie, un fichier peut contenir n'importe quelles données, or il me semble que toutes les méthodes de lecture, dans tous les langages, fonctionnent grosso modo pareil -- du coup, comment n'importe quel programme pourrait-il lire un fichier ?

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Grâce à un membre d'un autre forum j'ai pu obtenir ceci :

    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
    AnsiString Trame;
            U32 nb=P_L_ComRS_nb_byte_file(name_file);
            char * ligne_lue = new char[nb];
            ifstream file_to_send;
            file_to_send.open(name_file,ios::binary);
     
            while(file_to_send.read(ligne_lue, nb)) {
                    std::streamsize octets_reellement_lus = file_to_send.gcount();
                    Trame += AnsiString(ligne_lue, octets_reellement_lus);
            }
            if(Trame.Length() < nb) {
                    //erreur
            }
            else
            {
                    AnsiString TrameAffichable;
                    for(int i = 1, size = Trame.Length(); i < size;  ++i)
                    {
                            if(Trame[i] == '\\')
                                    TrameAffichable += "\\\\";
                            else if(std::isprint(Trame[i]))
                                    TrameAffichable += Trame[i];
                            else
                                    TrameAffichable += "\\x" + AnsiString::IntToHex(Trame[i], 2);
                    }
            }
     
            file_to_send.close();
    Ce qui permet de vérifier que tout mon fichier d'entrée à bien été stocké dans mon AnsiString, le problème venait donc de l'affichage et non de la lecture comme je le pensais à la base.
    Un nouveau problème se pose lors de l'envoie maintenant, je dois transformer mon AnsiString en char *, et le code suivant ne fonctionne pas strcpy s’arrête lors de la lecture des caractères spéciaux :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    AnsiString Chaine_a_envoyer;//ou est stocké mon fichier
    ..
    char *Chaine=new char[Chaine_a_Envoyer.Length()+1];
    strcpy(Chaine,Chaine_a_Envoyer.c_str());
    C'est pourtant un bon moyen de convertir les AnsiString en char *..

  8. #8
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    Est-ce que tu as remarqué que c'était exactement ce que je te disais ?

    Sinon, strcpy s'arrête au premier 0x00 (le même problème que pour l'affichage).

    Donc memcpy avec l'argument size fonctionnerait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Non testé
    AnsiString Chaine_a_envoyer;//ou est stocké mon fichier
    ..
    char *Chaine=new char[Chaine_a_Envoyer.Length()+1];
    memcpy(Chaine,Chaine_a_Envoyer.c_str(), Chaine_a_Envoyer.Length()+1);
    Par contre, tu vas te retrouver toujours face au même problème : à toute utilisation de fonction s'attendant à un str(ing), l'utilisation va s'arrêter au premir 0x00.

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Oui oui j'ai remarqué, désolé de pas avoir compris plus tot
    je viens de tester avec memcpy et le resultat est le même du au "c_str()" comme tu le disais.

  10. #10
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    Normalement, memcpy copie les octets pointés, sans ce préoccuper des octets null.

    Après, il est possible que AnsiString ne stocke que les octets avant le premier NULL, auquel cas tu devras t'en passer. (je ne connais pas cette classe, qui est non standard)

    D'ailleurs, pourquoi ne pas simplement utiliser un vector<unsigned char> ? Ceci t'éviterait tous les problèmes de nul.

  11. #11
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    je viens d'essayer ça,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    vector<U8> Chaine(Chaine_a_Envoyer.Length());
     
    for(U16 i =1;i<=Chaine_a_Envoyer.Length();i++)
             Chaine[i]=Chaine_a_Envoyer[i];
    j'ai vérifié et ma Chaine_a_envoyer contient bien tout les caractères que je veux


    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
    const U8 envoi_chaine(AnsiString Chaine_a_Envoyer,AnsiString Char_Controle)
     {
            U32 NbOctet_Message;
            unsigned long nBytesWrite;
            char *Message = new char[2048];
     
            char *EolChar=new char[Char_Controle.Length()+1];
            strcpy(EolChar,Char_Controle.c_str());
     
            vector<U8> Chaine(Chaine_a_Envoyer.Length());
            for(U16 i =1;i<=Chaine_a_Envoyer.Length();i++)
            {
                    Chaine[i]=Chaine_a_Envoyer[i];
            }
     
            //on concatene le caractère de contrôle a notre chaine
            if(strcmp(EolChar,"CR")==0)
                    sprintf(Message,"%s%c",Chaine,0x0D);
            if(strcmp(EolChar,"LF")==0)
                    sprintf(Message,"%s%c",Chaine,0x0A);
            if(strcmp(EolChar,"LF/CR")==0)
                    sprintf(Message,"%s%c%c",Chaine,0x0A,0x0D);
            if(strcmp(EolChar,"CR/LF")==0)
                    sprintf(Message,"%s%c%c",Chaine,0x0D,0x0A);
            if(strcmp(EolChar,"")==0)
                    sprintf(Message,"%s",Chaine);
     
            // compter le nombre d’octet à envoyer
            NbOctet_Message = StrLen(Message);
            // écrire dans le fichier(ici dans notre port de com)
           WriteFile(hwi_comrs_hCom_,Message,NbOctet_Message,&nBytesWrite,NULL);         delete[] Message;
            delete[] EolChar;
     
            return 0;
    }
    Grâce a un sniffeur rs232, j'ai vu que les paquets de donnée qui sont envoyé ne sont pas les bons, il n'envoie pas 2048octets par trame.

  12. #12
    Membre éclairé
    Avatar de Ekleog
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2012
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2012
    Messages : 448
    Points : 879
    Points
    879
    Par défaut
    "sprintf(Message,"%s%c",Chaine,0x0D);"
    Voici l'erreur.
    sprintf va faire comme un strcpy pour ses arguments %s, et s'arrêtera dès qu'elle trouvera un \0.
    La solution devra àmha utiliser memcpy pour copier Chaine dans Message, puis ajouter manuellement le 0x0D.
    Et de même pour chacun des autres cas.
    (Au passage, il serait plus élégant d'utiliser une enum pour CharControle et un switch au lieu des if. En plus, ce serait plus rapide.)

  13. #13
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 7
    Points : 2
    Points
    2
    Par défaut
    Voila la solution que l'on m'a donnée sur un autre forum, si ça peut aider quelqu'un :
    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
     
    const U8 envoi_chaine(AnsiString Chaine_a_Envoyer,AnsiString Char_Controle)
    {
        // Comme Chaine_a_Envoyer est déjà une copie de l'originale, on peut la modifier 
        // pour ajouter les caractères de contrôle 
        if(Char_Controle == "CR") 
           Chaine_a_Envoyer += "\r";
        else if(Char_Controle == "LF") 
           Chaine_a_Envoyer += "\n"; 
        else if(Char_Controle == "LF/CR")
           Chaine_a_Envoyer += "\n\r";
        else if(Char_Controle == "CR/LF")
           Chaine_a_Envoyer += "\r\n";
     
        unsigned long nBytesWrite = 0;               
        if(!WriteFile(hCom_,
                      Chaine_a_Envoyer.c_str(),
                      Chaine_a_Envoyer.Length(),
                      &nBytesWrite,
                      NULL))
        {
            // erreur
        }
        return 0;
    }
    Beaucoup plus simple que ce que je pensais à la base. Et qui fonctionne très bien merci quand même pour votre aide.

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 11/08/2014, 12h13
  2. Comment inclure un fichier non vital dans l'installeur?
    Par Sunsawe dans le forum Général Dotnet
    Réponses: 2
    Dernier message: 11/10/2007, 14h46
  3. [HTML] Inserer un fichier text (".txt") dans une page HTML
    Par silverfab34 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 04/10/2007, 11h57
  4. lien vers fichier non placer dans répertoire: 3w
    Par cobra85 dans le forum Apache
    Réponses: 1
    Dernier message: 22/08/2007, 09h25
  5. fichier non trouvé dans apache?
    Par darkbob dans le forum Web
    Réponses: 1
    Dernier message: 18/07/2006, 03h03

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