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 :

lecture binaire d'un fichier avec header incorporé


Sujet :

C++

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 17
    Points : 21
    Points
    21
    Par défaut lecture binaire d'un fichier avec header incorporé
    Bonjour,

    Pour lire un fichier (DBF par exemple) il suffit de connaitre sa structure et à partir de celle ci extraire une ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     
     cout << "taille record = " << m_file_header.dh.rsize;
            char record[m_file_header.dh.rsize];
            fread( &record , sizeof(record) , 1 , this->ptr_base );
    Ma question :
    Je connais la taille globale d'un record
    Celui ci est constitué de char[X] ou d'integer, etc.. mais la nature des champs varie d'un fichier à l'autre et je souhaiterais être capable à partir d'un record entier, extraire les différents champs quelques soient leurs natures.

    Concrêtement, je veux lire toto.dbf
    Le code c++ va me dire dans le header(seulement à l'execution) que ce fichier contient pour chaque enregistrement, les champs
    1 char[10]
    1 char[35]
    1 integer

    comment créer une sorte de structure de lecture 'online' c'est à dire durant l'execution?

    Aprés avoir trainé sur le forum, je pensais à la manipulation de pointeurs mais j'avoue que je pêche un peu par manque de pratique.

    Je pensais aussi lire champs par champs(car je connais la taille de chaque champ lors de l'éxécution) mais ce n'est pas très élégant.

    La finalité est de faire un lecteur de DBF perso pour me rôder à la pratique du c++.

    Merci pour votre aide ou/et une bonne pratique dans ce domaine.

    Cordialement,

    Gilles

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 374
    Points : 41 541
    Points
    41 541
    Par défaut
    Au sein d'un même fichier, les champs sont identiques non?
    Et donc, tu as une description des champs dans le header du fichier?

    Eh bien, tu peux mémoriser cette description, déjà, puis t'inspirer des bibliothèques d'accès aux bases de données pour les accès aux différents champs. Généralement, elles sont des méthodes GetXxxx(index) pour accéder au champ d'une colonne donnée en utilisant le type donné par le nom de la fonction:
    Code C++ : 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
    int CDefinitionTable::GetInt(unsigned char const* pData, int colonne)
    {
    	if(m_definitionColonnes[colonne].eType != TYPECOLONNE_INT)
    		throw mauvais_type(colonne, m_definitionColonnes[colonne].eType, TYPECOLONNE_INT);
    	int const * pValeur = reinterpret_cast< int const * >(data + m_definitionColonnes[colonne].offset);
    	return *pValeur;
    }
     
    std::string CDefinitionTable::GetString(unsigned char const* pData, int colonne)
    {
    	if(m_definitionColonnes[colonne].eType != TYPECOLONNE_CHAR
    	 && m_definitionColonnes[colonne].eType != TYPECOLONNE_NCHAR)
    		throw mauvais_type(colonne, m_definitionColonnes[colonne].eType, TYPECOLONNE_CHAR);
    	if(m_definitionColonnes[colonne].eType == TYPECOLONNE_CHAR)
    	{
    		char const * pValeur = reinterpret_cast< char const * >(data + m_definitionColonnes[colonne].offset);
    		return std::string(*pValeur);
    	}
    	else
    	{
    		wchar_t const * pValeur = reinterpret_cast< wchar_t const * >(data + m_definitionColonnes[colonne].offset);
    		std::wstring strW(pValeur);
    		std::string strA = ConvertirWcharEnChar(strW);
    		return strA;
    	}
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre à l'essai
    Inscrit en
    Avril 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 17
    Points : 21
    Points
    21
    Par défaut précision sur ma question
    Bonjour,

    En fait, je n'ai sans doute pas été assez précis

    l'idée est de constituer une structure dynamique pour lire un fichier binaire structuré. Pas forcément une base de donnée.

    Si on a une structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    struct{
     
    char[70] nom;
    char[70] prenom;
    int age;
     
     
    }mon_record
    celle ci est clairement definie, prete à l'emploi.
    Mais je voudrais pouvoir définir une structure à la volée car j'ignore la structure d'un 'record' de ce fichier(il est défini dans le 'header' du fichier) .
    Ainsi, à l'exécution je pourrais définir une structure (3 fois un int + 1 char, ou 2 fois un short int et 2 char[150], etc...)

    Merci

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 374
    Points : 41 541
    Points
    41 541
    Par défaut
    Tu ne peux.
    Le mieux que tu puisses faire, c'est un truc dynamique dont les champs sont repérés par index ou par nom. Mais tu ne pourras y accéder que dynamiquement, jamais directement.
    • La méthode bourrine et lourde, c'est de faire de chaque "ligne" une map consultée par nom de champ.
    • La méthode plus compliquée, mais moins lourde et optimisable pour le traitement à grande échelle de "lignes" identique, c'est de mettre la map (consultée par nom, index de colonne, etc.) dans une classe à part, qui retourne des offsets dans la zone mémoire de l'objet, et utiliser l'offset retourné pour accéder aux champs. Mon post en était un exemple incomplet.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre à l'essai
    Inscrit en
    Avril 2007
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 17
    Points : 21
    Points
    21
    Par défaut
    ok,

    Maintenant j'en ai le coeur net
    Je vais opter pour la lecture d'une ligne complète et un séquençage en fonction des types 'connus' que j'ai en ma possession(toujours des types char mais de longueur variable et je dispose d'un header m'indiquant la longueur des char, donc seul la taille variera)

    Merci bien en tout cas.

    Cordialement,

    Gilles

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

Discussions similaires

  1. Lecture binaire d'un fichier à un offset précis
    Par israel.jeremy dans le forum Général VBA
    Réponses: 17
    Dernier message: 22/08/2011, 17h14
  2. include dans un fichier avec header text/javascript
    Par shawidoom dans le forum Langage
    Réponses: 7
    Dernier message: 13/06/2011, 21h51
  3. Lecture binaire d'un fichier image
    Par RyuKa dans le forum Débuter
    Réponses: 8
    Dernier message: 02/06/2011, 16h03
  4. Lecture binaire d'un fichier VB6
    Par toss.net dans le forum C#
    Réponses: 4
    Dernier message: 23/01/2010, 18h50
  5. parser un fichier avec header
    Par czezko dans le forum Windows Forms
    Réponses: 8
    Dernier message: 08/01/2009, 14h52

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