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 formattée dans un fichier binaire


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2002
    Messages : 162
    Points : 88
    Points
    88
    Par défaut Lecture formattée dans un fichier binaire
    Bonjour,

    Je dois lire un fichier construit en concaténant d'autres fichiers, genre une archive. Certains sont "binaires", genre un fichier png, d'autres "texte", genre un fichier texte. Je connais la position de chaque fichier, et le nombre d'octets qu'il occupe.

    J'aimerais pouvoir lire la partie texte du gros fichier, comme si il s'agissait d'un fichier texte indépendant.

    Pour cela, je fais un truc comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::stringstream str;
    std::ifstream f( "...", std::ios::binary ); /* l'archive */
     
    f.seekg( debut_du_texte, std::ios::beg );
     
    /*faire des f.read() et str.write() jusqu'à avoir lu tous les octets du texte dans le stringstream*/
    Ensuite j'utilise le stringstream comme si c'était un fichier ouvert en mode texte.

    Le problème est que, sous windows, je me retrouve avec des '\r' en fin de lignes. Je crois que comme le fichier d'archive est ouvert en binaire, les traitements sur le str; comme std::getline( line, str ), gardent les '\r'.

    Pour résumer : ça marche pas, et je capte pas pourquoi. Je m'attendais à ce que le stringstream, un flux en mode texte donc, dégage les '\r'. Mais il ne le fait pas. Peut-être que normalement ce traitement est fait en amont ? genre dans les std::basic_streambuf et que mon code passe à coté ?

    Voilà donc. Si vous avez des idées à me donner, je vous serais reconnaissant.

    Merci

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    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 369
    Points : 41 519
    Points
    41 519
    Par défaut
    J'ignore s'il y a des trucs déjà prêts pour ça, mais si tout le reste échoue, tu pourrais toujous te faire ton propre streambuf intermédiaire qui lit le stream binaire et supprime les \r...
    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 actif
    Profil pro
    Dev
    Inscrit en
    Décembre 2007
    Messages
    191
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Décembre 2007
    Messages : 191
    Points : 216
    Points
    216
    Par défaut
    1) les caractères de fin de ligne varient d'un système à l'autre. Donc enregistrer des caractere de fin de ligne linux, fera qu'on vera des trucs bizarre en windows et inversément, à moins de prévoir cela dans le programme

    2) les stringstream m'ont déjà posé ce genre de problème. Je me suis résigner à lire mes fichiers texte ainsi pour préserver tous les caractères. (ainsi si un fichier est format windows, il le reste, etc....) :
    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
     
    string * lireTexte(const string & nomFichierTexte) {
    	ifstream fichier(nomFichierTexte.c_str(), ios::in | ios::ate);
     
    	size_t tailleFichier=fichier.tellg();
     
    	string * texte = new string("");
     
            texte->reserve(tailleFichier);
     
    	fichier.seekg(0); 
     
    	while (! fichier.eof() ) {
    		(*texte) += fichier.get();
    	}
     
    	fichier.close();
            return texte;
    }
    PS : bon y'a pas de vérification d'erreur, c'est pas très propre, mais la manière de faire marche très bien.

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Bonjour,
    je ne sais pas trop si je vais dire une connerie mais bon
    ne peut tu pas ouvrir un ifstream en binaire et un istream en test et leur faire cohabiter leur buffer?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::stringstream str;
    std::ifstream f( "...", std::ios::binary ); /* l'archive */
    std::istream fTxt;
    fTxt.rdbuf(f.rdbuf);
    http://www.cplusplus.com/reference/i...ios/rdbuf.html

    ouu charger toute la partie du fichier text et le mettre dans le streambuffer
    d'un istream (ou ifstream)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::vector<char> textFile;
    std::istream fTxt;
    ...//bufferiser le fichier 
    ftxt.rdbuf()->pubsetbuf(&textFile[0],textFile.size());
    http://www.cplusplus.com/reference/i...pubsetbuf.html

    Voici un autre lien dans FAQ
    http://cpp.developpez.com/faq/cpp/?p...SL_redirection

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    162
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Mai 2002
    Messages : 162
    Points : 88
    Points
    88
    Par défaut
    Merci pour vos réponses,

    Écrire un streambuf demande quand même un peu de boulot, et du coup je préfère écrire ma fonction getline qui fait un std::getline puis supprime les '\r' à la fin de la ligne lue.

    Citation Envoyé par Mongaulois Voir le message
    Bonjour,
    je ne sais pas trop si je vais dire une connerie mais bon
    ne peut tu pas ouvrir un ifstream en binaire et un istream en test et leur faire cohabiter leur buffer?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::stringstream str;
    std::ifstream f( "...", std::ios::binary ); /* l'archive */
    std::istream fTxt;
    fTxt.rdbuf(f.rdbuf);
    ...
    Je ne connaissais pas cette façon d'affecter un rdbuf. Malheureusement ça ne marche pas. Tout d'abord le constructeur de std::istream est protégé et je ne peux le construire ainsi. Ensuite, en bidouillant un peu avec l'autre partie que tu proposes, j'arrive à mettre le rdbuf de f dans un std::istringstream. Mais là encore c'est un échec.

    J'en suis à un code comme :

    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
      std::ifstream f(argv[1], std::ios::binary);
      char buffer[1000];
     
      f.read( buffer, 1000 );
      f.close();
      unsigned int n = f.gcount();
     
      std::istringstream iss;
      iss.rdbuf()->pubsetbuf( buffer, n );
     
      std::string line;
     
      while ( std::getline(iss, line) )
        std::cout << line << std::endl;
     
      iss.clear();
      iss.rdbuf()->pubsetbuf( buffer, n );
     
      while ( iss >> line )
        std::cout << line << std::endl;
    J'applique le code sur le fichier suivant :

    Citation Envoyé par le fichier
    ./out_text.exe\r\n
    a\r\n
    b\r\n
    c\r\n
    d\r\n
    La première boucle while affiche les lignes avec des '\r' à la fin. Donc comme le std::endl ajoute aussi un \r\n, je me retrouve avec \r\r\n à la fin de chaque ligne. La deuxième boucle rend bien le résultat attendu, mais ne fonctionnerait pas si il y avait des espaces dans le fichier.

    Comme je l'ai dit plus haut, refaire une fonction getline résout le problème (et prend moins de temps que d'écrire ce post), mais si il y a un moyen de le faire avec l'existant, je préférerais.

    Merci

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    j'ai essayer....
    C'est bizzare, j'ai le même problème que j'ouvre le fichier en txt ou en binaire(sous ubuntu)

Discussions similaires

  1. [Débutant] C# sous Win8, lecture dans un fichier binaire en asynchrone
    Par yupa dans le forum C#
    Réponses: 2
    Dernier message: 14/06/2012, 14h35
  2. Lecture erronée de float dans un fichier binaire
    Par Bourrine dans le forum Langage
    Réponses: 10
    Dernier message: 23/05/2012, 09h12
  3. Lecture dans un fichier binaire
    Par crashtib dans le forum C
    Réponses: 3
    Dernier message: 28/05/2009, 15h13
  4. Lecture ecriture dans un fichier binaire
    Par laetous dans le forum C
    Réponses: 13
    Dernier message: 26/08/2006, 08h50
  5. ouverture/lecture/ecriture dans un fichier en mode binaire
    Par dirty_boy dans le forum Débuter
    Réponses: 2
    Dernier message: 15/03/2006, 08h38

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