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++ Discussion :

codes ascii non reconnus


Sujet :

C++

  1. #1
    Membre du Club
    Inscrit en
    Mars 2007
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 82
    Points : 41
    Points
    41
    Par défaut codes ascii non reconnus
    Bonsoir,
    en ce moment j'essaye de crypter un fichier texte, pour cela je lis le fichier source caractère par caractère, je modifie leurs code ascii (j'obtiens alors un nouveau code pour chaque caractère entre 0 et 255)et ensuite je retrouve mon fichier cryptée comme désiré, cependant au moment de la lecture du fichier crypté pour une opération de décryptage, un premier problème surgis... la taille su fichier crypté n'est pas correctement calculé, ensuite il n'arrive pas a reconnaitre tous les caractère et ne parvient pas donc à décrypter le fichier dans sa totalité, je n'arrive pas à résoudre ce problème, en faite je ne comprends même pas ce qui se passe .
    merci de bien vouloir m'aider si un de vous a déjà rencontré ce problème.

  2. #2
    Membre habitué
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 153
    Points : 168
    Points
    168
    Par défaut
    Sans quelques bouts de code, ça va être difficile.
    Comment ouvres tu le fichier ?
    Comment lis tu la taille du fichier ?
    Que signifie :
    il n'arrive pas a reconnaitre tous les caractère
    --
    Jérémie
    Jérémie

  3. #3
    Membre du Club
    Inscrit en
    Mars 2007
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 82
    Points : 41
    Points
    41
    Par défaut
    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
     
     
    taille=0;
    FILE*  pFile_crypte;
    fopen(OpenDialog1->FileName.c_str(),"r");
    while(fgetc(pFile) != EOF) {taille ++;}
     
    x0=new long double[taille];
    fseek (pFile, 0, SEEK_SET);
    i=0;
     
       if(pFile==NULL) {cerr<<"problème de chargement \n";return;}
     
       while ( (c= fgetc (pFile)) != EOF)
          {
             ascii=mod((int)c,256);
             x0[i]= ascii;
             i++;
          }
       fclose (pFile);
    voila le code que j'utilise pour la récupération du code ascii, ça marche seulement pour le cryptage et j'obtiens les caractères suivant:

    ÂQÕœfˆ*aöG¨?*M mß°Y öW*
    Ã4ÖîG›ó×%:3¼yÇѱTà@óƒ·LàÇyÃXDŒ²>ˆwÜq?Híj¥)÷M4w“¨üYùØb?

    dont le code ascii varie entre 0 et 255, mais au moment de décrypter ce résultat, donc ces caractères, il ne reconnait par exemple que 20 caractères au lieu de 50, je suppose que un des caractère non reconnus est le .
    comment faire pour que tous les caractère puissent être lus et reconverti.

  4. #4
    Membre habitué
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 153
    Points : 168
    Points
    168
    Par défaut
    Salut

    Tu lis ton fichier en mode text, ce qui n'est pas bon dans ton cas, lit le en mode binaire ("rb" au lieu de "r").

    De plus, tu peux (largement) optimiser ce code pour ne pas effectuer 2 passes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    FILE* pFile_crypte = fopen(OpenDialog1->FileName.c_str(),"rb");
    if (pFile==NULL) {
      cerr<<"problème de chargement" << std::endl;
      return;
    }
     
    std::vector<long double> content;
    while ( (c = fgetc(pFile)) != EOF) {
      content.push_back( mod((int)c,256) );
    }
    fclose(pFile);
    (sans tout bien comprendre pourquoi des long double...)
    --
    Jérémie
    Jérémie

  5. #5
    Membre du Club
    Inscrit en
    Mars 2007
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 82
    Points : 41
    Points
    41
    Par défaut
    avec plus de tests, j'ai compris que le problème venait du code ascii étendu, en faite les codes ascii entre 128 et 255 ne peuvent pas être récupérés grace à la fonction:
    (int) c;
    alors maintenant je pose une question plus précise, comment récupérer le code ascii étendu??

  6. #6
    Membre habitué
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 153
    Points : 168
    Points
    168
    Par défaut
    Tu as essayé en mode "rb" ?
    De plus, la fonction getc renvoie un int, donc ta variable c doit être un int (pas besoin de cast dans (int) c).
    Si ton fichier est crypté, il n'est plus question d'ASCII (et étendu).
    --
    Jérémie
    Jérémie

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 624
    Points : 30 667
    Points
    30 667
    Par défaut
    Salut,

    D'abord, une remarque préliminaire, mais primordiale...

    Le code que tu présente est visiblement écrit en C, alors que tu a choisi de poser ta question sur le forum C++.

    La seule utilisation de cerr (seule fonction réellement propre au C++ que tu utilise) peut effectivement passer pour "une erreur"

    Deux solutions s'offrent alors à toi:
    • Soit, tu nous confirme bien que tu veux utiliser le C, auquel cas nous nous ferons un plaisir de déplacer la discussion dans la section ad-hoc,
    • Soit tu nous confirme, au contraire, que tu veux travailler en C++, auquel cas, il faudrait revoir tout depuis le début pour renoncer à l'utilisation de la structure FILE et des fonctions associées (mais nous pouvons t'aider sur ce point ).
    Ceci dit, il faut que tu prenne conscience que, que ce soit en C ou en C++, il existe toute une série de caractères qui ne sont pas imprimables et qui peuvent être particulièrement mal interprétés lorsque tu essaye de les lire dans un fichier.

    Il s'agit, entre autres, de tous les caractères compris entre 0 et 31 inclus (0x0 à 0x1F inclus en hexadécimal).

    Parmi tous ces caractères, on retrouve le retour à la ligne (dont la représentation réelle peut varier d'un système à l'autre) '\n', et tous les caractères nécessitant un échappement lorsque l'on souhaite les utiliser ('\t','\r','\0' et tous les autres)

    Si, pour une raison ou une autre, ta fonction de cryptage a pour effet de donner l'un de ces caractères "particuliers", l'écriture en mode texte (et surtout la lecture du fichier par la suite) sera prédestinée à poser un nombre important de problèmes

    Il faut donc, effectivement, t'arranger pour que les informations soient lue et écrite sous la forme de données brutes (autrement dit en écrivant ces données sous la forme d'un fichier (injustement) dit "binaire")

    Je ne vais pas m'étendre d'avantage sur la solution à ton problème avant de t'avoir laissé l'occasion de nous confirmer le langage que tu souhaite utiliser, de manière à éviter de te "perturber" inutilement avec des considération qui risquent d'être eronées selon le langage que tu veux utiliser

    Passe une bonne soirée
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par eclipse2007 Voir le message
    avec plus de tests, j'ai compris que le problème venait du code ascii étendu, en faite les codes ascii entre 128 et 255 ne peuvent pas être récupérés grace à la fonction:
    (int) c;
    alors maintenant je pose une question plus précise, comment récupérer le code ascii étendu??
    Probablement, ta variable c est un char, et ta machine considère que les char sont signés... Donc, les valeurs comprises entre 128 et 255 sont considérées comme négatives quand tu les mets dans c.

    Ensuite, la conversion (int)c préserve ces valeurs négatives, et tu as "perdu" ces codes 128 à 255.

    Si c'est effectivement ton problème (regarde la définition de c), tu peux

    - soit en faire un unsigned char, tout devrait alors rentrer dans l'ordre (c'est en général une bonne idée, quand tu travailles sur des données qui sont traitées comme du code binaire, d'utiliser des variables unsigned...). Tu n'auras d'ailleurs plus besoin du mod(,256) derrière, je pense.

    - soit, comme l'a suggéré Jérémie, de convertir c en int. Comme de toutes façons tu le fais quelques lignes plus loin, c'est du temps de gagné. (là encore, je ne crois pas que le mod(,256) soit nécessaire...)

    Francois

  9. #9
    Membre du Club
    Inscrit en
    Mars 2007
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 82
    Points : 41
    Points
    41
    Par défaut
    bonjour, merci pour votre réponse, en faite je travaille avec borland c++ builder 6 et je souhaite écrire mon programme en c++, j'attends votre solution avec impatience, il faut dire que ce problème m'a pris beaucoup de temps, j'ai fait plein de tests qui m'ont mené à rien.
    cordialement

  10. #10
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Si tu veux l'écrire en C++ alors utilise les flux. fstream pour la lecture / écriture du fichier notamment :
    http://cpp.developpez.com/faq/cpp/?page=fichiers
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  11. #11
    Membre du Club
    Inscrit en
    Mars 2007
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 82
    Points : 41
    Points
    41
    Par défaut
    bonsoir,
    j'ai réussi a lire le fichier caractère par caractère et cela d'une manière correcte sans erreurs, et cela en utilisant les streams, j'utilise le code suivant au tout début pour calculer le nombre de caractère qui se trouvent dans le fichier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    myfile.open("fichier.txt");
    if (myfile.is_open())
      {
        while (! myfile.eof() )
        {
          myfile>>c;
          taille=taille+1;
        }
        myfile.close();
      }
    pour me repositionner au début du fichier j'utilise l'instruction suivante:
    myfile.seekg(pos,std::ios_base::beg ) ;
    et cela après avoir récupéré la valeurs de pos avant le calcul de la taille du fichier:
    pos = myfile.tellg();
    seulement si j'affiche la valeur de pos, elle est égale à -1 au lieu de 0, je ne comprend pas le problème.
    une solution provisoire mais pas très efficace est de fermer et de réouvrir le fichier, qu'avez vous à me proposer!!
    merci pour vos réponse

  12. #12
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 624
    Points : 30 667
    Points
    30 667
    Par défaut
    Il y a juste deux chose à prendre en compte avec ton code:
    • Il est préférable de ne pas utiliser eof() pour mettre fin à la lecture (cf l'entrée de la FAQ correspondante), parce que la lecture peut échouer pour d'autres raisons
    • A moins que tu n'aie une bonne raison de la faire, il est inutile d'invoquer la fonction close() sur ton fichier une fois qu'il a été lu entièrement: il sera automatiquement et correctement fermé lorsque la variable myfile sera détruite (c'est à dire lorsqu'on sortira de la portée de sa déclaration)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  13. #13
    Membre du Club
    Inscrit en
    Mars 2007
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 82
    Points : 41
    Points
    41
    Par défaut
    c'est bon tout marche à la perfection, pour ceux qui risquerai d'en avoir besoin voici mon code pour lire un fichier texte caractère par caractère:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    myfile.open("fichier.txt");    
    myfile.seekg (0, ios::end);
    taille = myfile.tellg();
    myfile.seekg (0, ios::beg);
    buffer = new char [taille];
    myfile.read (buffer,taille);
    myfile.close();
    merci à vous pour votre aide

  14. #14
    Invité
    Invité(e)
    Par défaut
    Juste un petit truc supplémentaire : quand tu ouvres un fichier, tu peux directement te positionner à la fin en utilisant le parametre ios::ate

    Tu pourrais ici faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    myfile.open("fichier.txt",ios::ate);    
    taille = myfile.tellg();
    myfile.seekg (0, ios::beg);
    Maintenant, ce code pose un problème intéressant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myfile.open("fichier.txt");
    Ouvre le fichier en mode texte

    myfile.tellg() renvoie sa taille en octets.
    mais, sous Windows, si le fichier contient des retours chariot, myfile.read(ch,taille) ne va pas lire taille caractères, mais un peu moins (car chaque retour, qui occupe deux caractères dans le fichier, ne sera lu que comme un seul dans ch.

    Du coup, taille n'est pas la "vraie" taille de la chaine de caractère que tu lis...

    Por t'en convaincre, tu peux essayer de comparer les résultats, sur un petit fichier contenant du texte avec des retours chariot, des programmes suivants

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            ifstream fdat("test.txt",ios::ate);
            int l=fdat.tellg();
            cout<<l<<endl;
            fdat.seekg(0,ios::beg);
            char *ch=new char[l];
            fdat.read((char*)ch,l);
            for(int i=0;i<l;i++) cout<<i<<" "<<(int) ch[i]<<endl;
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            ifstream fdat("test.txt",ios::binary|ios::ate);
            int l=fdat.tellg();
            cout<<l<<endl;
            fdat.seekg(0,ios::beg);
            char *ch=new char[l];
            fdat.read((char*)ch,l);
            for(int i=0;i<l;i++) cout<<i<<" "<<(int) ch[i]<<endl;
    La valeur de l est la même dans les deux cas, mais chez moi (sur un fichier de 19 octets avec deux retours chariot...) le premier renvoie :

    19
    0 49
    1 50
    2 32
    3 49
    4 51
    5 32
    6 49
    7 56
    8 32
    9 54
    10 57
    11 10
    12 50
    13 49
    14 10
    15 50
    16 51
    17 0
    18 0

    et le second :

    19
    0 49
    1 50
    2 32
    3 49
    4 51
    5 32
    6 49
    7 56
    8 32
    9 54
    10 57
    11 13
    12 10
    13 50
    14 49
    15 13
    16 10
    17 50
    18 51

    En fait, quand le fichier est ouvert en mode texte, la chaine lue ne fait que 17 caractères, et deux caractères nuls (je ne suis pas certain que ce soit garanti...) sont ajoutés à la fin...

    tellg en mode texte, mefiance !

    Francois

  15. #15
    Membre du Club
    Inscrit en
    Mars 2007
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 82
    Points : 41
    Points
    41
    Par défaut
    vous avez tout a fait raison, j'ai fait ce test il y a quelques jours et comme vous le dite la taille ne correspond pas exactement au nombre de caractères qui se trouvent dans le fichier, donc le remplissage du tableau ne se fait pas jusqu'à la fin d'où les caractères nuls qu'on retrouve à la fin.
    j'ai omis hier de mentionner que j'ouvrais mon fichier avec ios::binary comme option, et la le nombre de caractère est exactement le bon.
    merci pour cette réflexion constructive!!

  16. #16
    Invité
    Invité(e)
    Par défaut
    En y refléchissant, j'ai deux questions, maintenant....


    1- y a-t-il un moyen de déterminer le nombre d'octets lus dans un fichier en mode texte, sans lire tout ce fichier ?
    2- y a-t-il (sur des système d'exploitation usuels) d'autres combinaisons de caractères que le retour chariot qui sont ainsi interprétées différemment en mode texte et en mode binaire ?

    Francois

  17. #17
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 624
    Points : 30 667
    Points
    30 667
    Par défaut
    Citation Envoyé par fcharton Voir le message
    En y refléchissant, j'ai deux questions, maintenant....


    1- y a-t-il un moyen de déterminer le nombre d'octets lus dans un fichier en mode texte, sans lire tout ce fichier ?
    2- y a-t-il (sur des système d'exploitation usuels) d'autres combinaisons de caractères que le retour chariot qui sont ainsi interprétées différemment en mode texte et en mode binaire ?

    Francois
    En un mot: tous les caractères ASCII dont le code va de 0 (0x0 hexa) à 31 (0x1F hexa) vont poser problème lors de la lecture en mode texte.

    Si tu veux savoir ce que représentent ces différents code, je te conseille de te reporter à la table ASCII telle que définie par l'ANSI (enfin, il me semble que c'est l'ANSI qui l'a définie )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  18. #18
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par koala01 Voir le message
    En un mot: tous les caractères ASCII dont le code va de 0 (0x0 hexa) à 31 (0x1F hexa) vont poser problème lors de la lecture en mode texte.
    En es tu sûr?

    Le code 0x09, qui représente la tabulation, se lit sans problème en mode texte, non? Quand on l'imprime à l'écran, il ne s'imprime pas comme un caractère, mais read() ne fait pas de différence entre le mode texte et le mode binaire...

    Il me semble également qu'un caractère 13 (0x0D) non suivi par un 10 (0x0A) est correctement lu en mode texte... Même le 0 ne pose aucun problème, tant qu'on n'essaie pas de lire le contenu du buffer renvoyé par read() comme une chaine "façon C"...

    Mais j'ai probablement mal formulé ma question... Ce que j'essaie de savoir ce sont les cas dans lesquels

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    monfich.read(buff,taille);
    renvoie un contenu différent dans buff suivant que monfich est ouvert en mode binaire ou en mode texte...

    En fait, en y réfléchissant, je ne connais que deux différences de comportement de read() en binaire et en texte, et encore pas sur tous les systèmes...

    - sur certains systèmes, les retour chariots (séquence 0x0D 0X0A remplacée par 0x0A)
    - sur certains systèmes, le caractère "fin de fichier", ou plutôt, je l'ai entendu dire, mais je ne sais pas si c'est le cas des OS actuels...

    En voyez vous d'autres?

    Francois
    Dernière modification par Invité ; 26/05/2009 à 20h42.

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

Discussions similaires

  1. Code ASCII du symbole Euro
    Par FW-S dans le forum Delphi
    Réponses: 9
    Dernier message: 03/04/2007, 01h27
  2. [Hardware portable] Comment entrer un code Ascii?
    Par l.sage dans le forum Ordinateurs
    Réponses: 13
    Dernier message: 11/08/2005, 13h04
  3. fonction redonnant le code ascii d'un entier ???
    Par abignon dans le forum MFC
    Réponses: 4
    Dernier message: 29/01/2004, 12h32
  4. [mx2004]Convertir un code ASCII en une lettre
    Par caramel dans le forum Flash
    Réponses: 3
    Dernier message: 28/01/2004, 16h26
  5. [TP]Code ASCII.
    Par franck H dans le forum Turbo Pascal
    Réponses: 12
    Dernier message: 18/01/2004, 19h28

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