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 :

sequencage de fichier


Sujet :

C++

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 127
    Par défaut sequencage de fichier
    Salut, je suis un ptit nouveau sur le forum, mais ca fait longtemps que je profite des diverses discussions, qui m'ont souvent depanné... enfin bref....

    Ma question est la suivante:

    J'ai un fichier qui contient des valeurs hexa. Je veux pouvoir mettre ce fichier sous forme de map.(ou autres conteneurs si vous avez mieux a proposer).
    Je dois lire le contenu du fichier puis des que j ai une valeurs hexa type (0x47) je copie le toutes les valeurs qui se trouvent jusqu'au prochain fanion(0x47).
    Il me semble que cela se fait assez facilement avec les map. mais je trouve pas comment???

    exemple: fichier: 47 a8 54 43 87 56 a1 c3 47 79 ...

    donc tout ce qui est entre les 47 doit etre copier dans un case de la map.

    merci d'avance

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 127
    Par défaut
    Enfin ca se fait plutot avec un iterateur je voulais dire mais je desire contenir mes données dans une map.

  3. #3
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Une map est une table associative : on associe une donnée à une clé ; la donnée sera retrouvée grâce à la clé.
    L'hexa n'est qu'une représentation textuelle que l'on applique sur des nombres.

    Je n'ai pas saisi ce que tu cherchais à faire.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 127
    Par défaut
    Merci de ta réponse, je vais essayer d'etre plus clair.
    le but est de decouper un fichier mpeg2 en sequence.
    Un fichier mpeg2 est compose de paquet, et chacun de ces paquets commence par un fanion(fanion = permet de determiner le debut d'un paquet)
    ce que je desire faire c'est mettre chacun des ces paquets dans une case de la map.

    Donc pour faire cela, je dois detecter le fanion puis copier tous les bytes dans la case de la map jusque'au prochain fanion.

    J'espere que c'est plus clair...

  5. #5
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    Tu ne veux pas une map. Une map te réordonnerai tes paquets selon l'ordre appliquable aux clés de stockages.
    Un simple vecteur de vecteurs fera très bien l'affaire dans ton cas.

    Je verais bien une lecture par blocs, et au fur et à mesure, tu découperais tes blocs (de lecture) en paquets séparés par des fanions. Un truc du genre:

    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    const char FLAG = 0x47;
     
    typedef std::vector<char> paquet_t;
    std::vector<paquet_t> paquets;
     
    std::ifstream f("nom fichier", std::ios_base::in|std::ios_base::binary);
    if (!f) throw std::runtime_error("cannot open ``nom fichier''");
    const size_t BUFFER_SIZE = 1024; // ou autre valeur intelligente
    std::vector<char> buffer(BUFFER_SIZE);
     
    // On peut même faire un buffer.reserve(NB) si on connait le nombre 
    // de paquets dans le fichier
    packets.resize(1);
    packet_t * current_packet = &packets.back();
     
    while (size_t nb_read = f.read(&buffer[0], buffer.size()) ) {
        if (nb_read != buffer.size()) 
            buffer.resize(nb_read); // c'est la fin du fichier, on maj buffer.end()
     
        packet_t::const_iterator f = v.begin();
        packet_t::const_iterator p = std::find(f, buffer.end(), FLAG) ;
        for ( ; p != buffer.end() ; p = std::find(f, buffer.end(), FLAG) )
        {
            ++p; // On absorbe le FLAG
     
            // On copie ce que l'on vent de lire à la fin du paquet courant
            std::copy(f, p, std::back_inserter(*current_packet) );
     
            // paquet suivant
            packets.resize(packets.size() + 1);
            current_packet= &packets.back();
     
            // Repositionnement du marqueur de début
            f = p; 
        }
     
        // On commence à mettre ce qui reste du buffer dans le dernier paquet
        // Mais on ne passe pas au paquet suivant car la suite va de nouveau arriver dans le buffer
        std::copy(f, buffer.end(), std::back_inserter(*current_packet));
    } // fin de la lecture
     
    // au cas où le dernier paquet ne contiendrait rien.
    if (!packets.empty() && (packets.back().size() == 0)) {
        packets.resize(packets.size() - 1);
    }

    Le code est certainement faux au niveau de sa machine à états (n supposant qu'il compile), mais il donne l'idée générale de ce qui doit être fait.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2006
    Messages : 127
    Par défaut
    Merci pour ta réponse, effectivement l'objet map n'est pas adapte a ce que je veux faire, vector est bien meilleure.
    la strategie que je vais utiliser est la suivante, je vais reparer le FLAG, puis creer objet paquets (qui contient mon paquets). Puis stocker tous ces paquets dans un vector.
    ainsi mon vector sera une sequence de paquet.

    Mais j'ai quelque question concerant les iterateurs.
    1. Est-ce que je peux passer un ou des iterateurs en parametre d'un constructeur pour construire mon objet paquets a partir des iterateurs?
    2. Est ce que je peux faire une comparaison du type == avec des valeurs hexa declaré comme caractere?
    3. derniere question, est ce que tu pourrais detailler ce qui se passe dans cette partie de code?

    packet_t::const_iterator f = v.begin();
    packet_t::const_iterator p = std::find(f, buffer.end(), FLAG) ;
    for ( ; p != buffer.end() ; p = std::find(f, buffer.end(), FLAG) )
    {
    ++p; // On absorbe le FLAG

    // On copie ce que l'on vent de lire à la fin du paquet courant
    std::copy(f, p, std::back_inserter(*current_packet) );

    // paquet suivant
    packets.resize(packets.size() + 1);
    current_packet= &packets.back();

    // Repositionnement du marqueur de début
    f = p;

    Merci d'avance

  7. #7
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 292
    Par défaut
    1- Un itérateur est une donnée comme une autre. Tu la passes à des fonctions si tu le veux. Ils servent à itérer sur des plages de données (ici j'ai fait ressortir des itérateurs sur le buffer lu).
    Une plage itérable étant définie par une paire d'itérateur [first,last[ -- ou [first,last) si on prend la notation anglo-saxone. La plage est "vide" ssi first==last.

    2- Un caractère est un nombre. Ainsi, 'A' == 65 == 0x41. tu l'auras compris, l'hexa n'est qu'un détail dont on n'a pas grand chose à faire.

    3- Le but est de parcourrir le buffer lu sur le disque pour extraire toutes les plages entre deux marqueurs.
    Ainsi,
    - f est initialisé sur le début du buffer
    - p est initialisé pour pointer sur le premier marqueur du buffer.
    Puis la boucle.
    - pas d'initialisation ; en fait l'init de p correspond à ce que l'on aurait pu faire dans le premier champs du for
    - On boucle tant que p ne pointe pas sur la fin du buffer (std::find() retourne la fin de la plage s'il ne trouve pas ce qu'on lui demande de chercher)
    - L'itération consistera à trouver le debut du paquet suivant

    Maintenant que j'y pense, il ne fallait peut-être pas absorber le flag -- inclure le marqueur en fin du paquet que l'on va extraire

    Le corps de la boucle consiste à copier (std::copy) tout ce qui est entre f (inclu) et p (exclu) à la fin (std::back_inserter) du paquet courant.
    Vu que l'on a atteint la fin du paquet, on passe au suivant -- i.e., on boucle f<-p et p est déplacé jusqu'au marqueur suivant, et on vérifie que p != buffer.end().

    Quand la boucle se termine, ce veut dire que l'on a atteint la fin du buffer lu. On copie alors ce qui dépasse dans le paquet courant (sans passer au suivant) car on va lire de nouveau dans le fichier.

    PS: Je voulais écrire readsome() et pas read()
    PPS:
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

Discussions similaires

  1. fichier mappé en mémoire
    Par WinBernardo dans le forum Delphi
    Réponses: 7
    Dernier message: 01/12/2006, 09h38
  2. Réponses: 5
    Dernier message: 20/08/2002, 18h01
  3. Lire 1 bit d'un fichier en C
    Par Anonymous dans le forum C
    Réponses: 3
    Dernier message: 23/05/2002, 18h31
  4. Comparer des fichiers de données : Quel Langage ?
    Par Anonymous dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 24/04/2002, 22h37
  5. Fichier PDOXUSRS.NET
    Par yannick dans le forum Paradox
    Réponses: 5
    Dernier message: 05/04/2002, 09h45

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