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 :

Tableau de char vers un autre type de données


Sujet :

C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 42
    Points : 18
    Points
    18
    Par défaut Tableau de char vers un autre type de données
    Bonjour, j'aimerais mélanger le mode binaire et le mode texte pour la lecture de fichier. Je m'explique:

    J'ai un fichier qui contient des données qui sont écrites de manière binaire (int double etc...) et ce même fichier contient aussi des données texte.

    Et j'aimerai récupéré les 2, pour cela je lis en entier le fichier en mode texte en remplissant un tableau de char.
    Ce dernier contient donc les données "texte" (donc facile à interpréter) mais comment je fais pour récupérer les données binaires? Exemple: un int qui prendra 4 éléments du tableau de char.

    Merci d'avance

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 214
    Points : 310
    Points
    310
    Par défaut
    C'est bien un simple tableau comme on le fait en C, pas un vector ou string de la stl ou autre mécanisme du C++ ?

    Dans ce cas, tu es sûr que tes données sont contiguës, et tu as juste à transmettre un pointeur vers le premier octet du int ou à copie la donnée à partir de cette l'adresse du premier octet, sur la taille de ta donnée (4 ici pour un int codé sur 4 octet (attention à ton environnement de travail, un int ne fait pas toujours 4 octets, parfois il peut faire plus)).

  3. #3
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Ça dépend, tu sais où sont tes valeurs ?

    Parce que si non, un bloc de 4 char peut être interprété comme un chaine de caractère (là tu vois vite si ça concorde ou pas), comme un float, comme un int, comme deux short, ... Là ça devient déjà plus dur. Mais là où ça se corse encore c'est si tu as par malheur un int dont la valeur peut être interprété comme une chaine de caractère...

    Donc soit tu sais ce que tu lis, soit tu fais au pif en essayant d'interpréter toi même.

    EDIT: si tu sais où sont tes valeurs c'est fichtrement simple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::ifstream f(nomfichier);
    f >> entier1 >> chaine1 >> entier2 >> double1;

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    Oui c'est un simple tableau.

    Mais je cherche pas forcément faire ça juste avec un int, c'est tout d’abord juste en théorie.

    Je sais pas si j'ai mal compris ou si je me trompe mais ce code ne fonctionne pas comme prévu :

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
        FILE* file = NULL; // Pointeur du fichier
        int num=123456; // Entier à inscrire dans le fichier
        char c[sizeof(num)]; // Tableau de char contenant l'entier lu
        file = fopen("file.txt", "wb"); // Mode binaire
     
        if (file != NULL){
            fwrite (num, sizeof(num), 1, file); // Ecriture binaire
            fclose(file);
        }
     
        file = fopen("file.txt", "r"); // Mode texte
        int i = 0;
        do{
      	    c[i] = fgetc(file); // Lecture texte
      	    i++;
    	}while(c[i-1] == EOF);
    	printf("resultat =%d\n",c);
     
        return 0;
    }

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 214
    Points : 310
    Points
    310
    Par défaut
    Pour le remplissage au fur et à mesure, l'exemple de Trademark est très bien.

    Sinon dans ton exemple, tu te butes aux difficultés des types de données.

    Un type, c'est plusieurs choses :
    - D'abord une façon d'interpréter les données que ce soit des types natifs au langage (entier non signé, signé en complément à 2, nom flottant IEEE754, caractère ASCII, booléen) ou des types composés (structure sans fonction).
    - Mais c'est aussi un encombrement mémoire.

    C'est pour cela qu'un tableau de char prendra moins de place qu'un tableau de int, et aussi que l'adresse de la ième case ne sera pas la même si ton tableau est un tableau de int ou de char.

    Ainsi, quant tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("resultat =%d\n",c);
    Tu dis à l'ordinateur de prendre un caractère de la taille d'un char, et d'afficher les données en tant que nombre. Et donc tu n'obtiens que le premier octet de ta ton type sur 4 octets.

    En code c (puisque tu es parti sur un exemple c et non c++), ma réponse de tout à l'heure devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int *pnum = &c[i];  //À l'adresse indiqué, on trouve un int
    //OU
    int num;
    memcpy(&num, &c[i], sizeof(num)); //À partir de l'adresse de num, et jusqu'à avoir atteint la taille occupée par num, on copie les données qu'on trouve à l'adresse indiquée, qui est celle de la ième case du tableau de char. 
    //OU
    int *pnum;
    memcpy(pnum, &c[i], sizeof(*num));

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    Merci je commence à y voir un peu plus clair

    Mais ce code ne fonctionne toujours pas

    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
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
        FILE* file = NULL; // Pointeur du fichier
        int num=123456; // Entier à inscrire dans le fichier
        float nom=123.456; // Réel à inscrire dans le fichier
        int* p_num;
        double* p_nom;
        char c[500]; // Tableau de char contenant l'entier lu
        file = fopen("file.txt", "wb"); // Mode binaire
     
        if (file != NULL){
            fwrite (&num, sizeof(num), 1, file); // Ecriture binaire
            fwrite (&nom, sizeof(nom), 1, file); // Ecriture binaire
            fclose(file);
        }
     
        file = fopen("file.txt", "r"); // Mode texte
        int i = 0;
        do{
      	    c[i] = fgetc(file); // Lecture texte
      	    i++;
    	}while(c[i-1] == EOF);
     
    	p_num = &c[0];
    	p_nom = &c[sizeof(int)];
     
     
     
    	printf("resultat =%d\n",p_num);
     
        return 0;
    }

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 214
    Points : 310
    Points
    310
    Par défaut
    Oups, vive le Little Endian !

    Lire caractère par caractère en mode texte c'est une chose, mais quand tu travailles comme ça avec ton tableau de donnée, tu dépends de la façon dont travaille ton processeur avec les nombres. Et comme tu as un PC de type x86 / Intel, les nombres sont stockés (revoir au besoin tes cours d'architecture de l'ordinateur) selon la méthode Little Endian (le chiffre 2 s'écrira 2 sur un caractère, mais 20 sur 2 caractères, 2000 sur 3 caractères).

    Pour éviter ce problème, tu ne dois pas lire caractère par caractère, mais tout ton flux, avec la fonction fread (puisque tu écrit avec fwrite).




    Et pour progresser tout seul, dans ces cas-là :
    - Affiche aussi tes valeurs en hexadécimal
    - Teste avec des valeurs remarquables (0, 1, 2, 0x10 (16), 0X1000 (4096), -1 (0xFFFF) etc)

  8. #8
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2011
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2011
    Messages : 42
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Jérôme_C Voir le message
    Oups, vive le Little Endian !

    Lire caractère par caractère en mode texte c'est une chose, mais quand tu travailles comme ça avec ton tableau de donnée, tu dépends de la façon dont travaille ton processeur avec les nombres. Et comme tu as un PC de type x86 / Intel, les nombres sont stockés (revoir au besoin tes cours d'architecture de l'ordinateur) selon la méthode Little Endian (le chiffre 2 s'écrira 2 sur un caractère, mais 20 sur 2 caractères, 2000 sur 3 caractères).

    Pour éviter ce problème, tu ne dois pas lire caractère par caractère, mais tout ton flux, avec la fonction fread (puisque tu écrit avec fwrite).




    Et pour progresser tout seul, dans ces cas-là :
    - Affiche aussi tes valeurs en hexadécimal
    - Teste avec des valeurs remarquables (0, 1, 2, 0x10 (16), 0X1000 (4096), -1 (0xFFFF) etc)
    D'accord, merci beaucoup ça m'a beaucoup aidé

    Problème résolu

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/04/2015, 23h10
  2. Vers un autre type de Mémoire ?
    Par Ododo dans le forum Actualités
    Réponses: 0
    Dernier message: 30/10/2014, 02h13
  3. tableau de char vers string hexa
    Par andromeda dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 22/07/2007, 23h10
  4. Pointeur générique vers d'autres types d'objets
    Par LapinGarou dans le forum MFC
    Réponses: 11
    Dernier message: 15/09/2006, 16h48
  5. copier une table vers une autre base de données
    Par Herveg dans le forum Oracle
    Réponses: 3
    Dernier message: 11/01/2005, 14h20

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