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

SL & STL C++ Discussion :

Lecture de fichier windows et Unix (CR/LF)


Sujet :

SL & STL C++

  1. #1
    Membre émérite
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par défaut Lecture de fichier windows et Unix (CR/LF)
    Bonjour,

    Je suis en train de m'énerver sur une méthode qui lit tout simplement des fichiers textes ligne par ligne.
    Je gère actuellement l'encodage ANSI, UTF8, etc...

    Par contre, je viens de réaliser que selon le type de fichier windows/Unix (CR/LF ou LF) je ne sais pas lire les données....
    Aucun soucis pour Unix, mais pas moyen de lire le windows (CR/LF).

    J'utilise std::getline pour le moment, mais j'arrive tout de suite sur EOF dès la 1ere ligne...
    Idem pour istream::getline ...

    Auriez vous une idée d'une méthode de lecture de fichier qu'il soit windows ou linux, quitte à faire un if avec 2 méthodes... (a condition de savoir distinguer les types...) ?

    Merci beaucoup.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Tu tests la condition de sortie sur eof?

  3. #3
    Membre émérite
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par défaut
    En fait, je prend un ifstream pour ouvrir mon fichier.

    je test le eof() => false
    je fait std::getline(...)
    je test le eof() => true

    le fichier est bien lu, depuis le debogeur de VS je vois même le début du contenu dans les champs du istream...

  4. #4
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    As tu pensais a widen(char) ?

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    En C++, pour lire un fichier ligne par ligne, c'est juste:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    std::ifstream file( "fichier" );
     
    if( file )
    {
        std::string line;
        while( std::getline( file, line  ) )
        {
     
        }
    }
    Sous linux par exemple ce code va gérer l'UTF-8 basique tout seul à l'affichage.

    Pour lire un fichier windows ( si tu es sous Linux ), il faut pas juste rajouter un paramètre à getline qui indique quel est le caractère de fin?

    http://www.cplusplus.com/reference/string/getline/
    istream& getline ( istream& is, string& str, char delim );
    istream& getline ( istream& is, string& str );

    c'est pas ça que tu recherches en fait?


    Le truc de getline, c'est qu'il n'a pas le même fonctionnement sous Linux ou sous Windows. Il prendra le format de fichier du système sur lequel il est compilé

  6. #6
    Membre émérite
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par défaut
    Citation Envoyé par nikko34 Voir le message

    Pour lire un fichier windows ( si tu es sous Linux ), il faut pas juste rajouter un paramètre à getline qui indique quel est le caractère de fin?


    c'est pas ça que tu recherches en fait?

    Possible, mais dans ce cas quels sont les carateres de fin sous windows et Unix ? '\n' ?

    Merci.

  7. #7
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Unix : \n
    Windows : \r\n

    Et de façon générale : ctype::widen('\n')...

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Sous unix : 0x0A.
    Sous windows : 0x0D 0x0A
    getline peut prendre en troisième paramètre un argument pour spécifier le char.

  9. #9
    Membre émérite
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par défaut
    Merci de vos réponses, mais j'arrive toujours à rien...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	std::locale loc;
    	std::getline(is, pBuffer, std::use_facet< std::ctype<wchar_t> >(loc).narrow( std::use_facet< std::ctype<wchar_t> >(loc).widen('\n')) );
    je suis contraint d'utiliser narrow car widen retourne un charT et non pas un char.

    ça lit les fichiers Unix, mais toujours pas les Windows...

    Sinon j'ai tenté avec \r\n, mais ce sont 2 carateres et non pas un seul... ce qui donne donc de mauvais résultats.
    Je me trouve ridicule sachant que je code en c++ depuis des années, mais là je rame péniblement pour utiliser cette méthode...

    Merci

  10. #10
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Un autre paradoxe de windows : le caractère de fin de ligne est deux oO !

    sinon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ios::imbue(locale("ce qu'il faut"))
    pour modifier directement ton flux. C'était peut-être la solution dès le début oO !

  11. #11
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par Lavock Voir le message
    Un autre paradoxe de windows : le caractère de fin de ligne est deux oO !
    C'est pas mieux en UTF-8 pour les caractères diacritiques, tu sais...

    Historiquement, le "bon" retour à la ligne serait plus CR/LF : CR ramène le curseur à la colonne 1 sans quitter la ligne courante, et LF passe à la ligne suivante... mais sans changer pour autant la colonne courante ! Donc, pour bien revenir à la première colonne de la ligne suivante, il fallait ces deux caractères.

    Mais bon, faut sûrement avoir connu des terminaux et/ou des imprimantes un peu "stupides" pour comprendre, je pense.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Ange_blond Voir le message
    Merci de vos réponses, mais j'arrive toujours à rien...
    Salut,
    Tu as un fichier exemple. J'ai un peu joué avec un fichier en changeant avec un éditeur hexa les fins de lignes unix/windows et je n'ai pas réussi à reproduire ton bug. getline s'en sort toujours

  13. #13
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Ou des machines à écrire (pour lesquels l'intérêt d'un retour en début de ligne existait >< )! Mais j'avoue, c'était surtout un vieux troll !

  14. #14
    Membre émérite
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Salut,
    Tu as un fichier exemple. J'ai un peu joué avec un fichier en changeant avec un éditeur hexa les fins de lignes unix/windows et je n'ai pas réussi à reproduire ton bug. getline s'en sort toujours
    Voilà 2 fichiers : le unix fonctionne et le win non.

    Je me sert de notepad++ pour choisir/changer le format.


    Merci.
    Fichiers attachés Fichiers attachés

  15. #15
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Bonjour,
    Avec vs2008, ce code :
    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
    #include <string>
    #include <iostream>
    #include <fstream>
     
    int main()
    {
    	std::string line;
    	std::ifstream if1("_unix.txt");
    	while(std::getline(if1, line))
    	{
    		std::cout << line << "\n";
    	}
     
    	std::ifstream if2("_win.txt");
    	while(std::getline(if2, line))
    	{
    		std::cout << line << "\n";
    	}
    }
    affiche
    V53S3261020000|M:\ROA\A350\vc\f11w3\V53S3261020000
    V53S1271620000|M:\ROA\A350\vc\f11w3\V53S1271620000
    V52S7158220000|M:\ROA\A350\vc\d11w1\V52S7158220000
    V53S3002920000|M:\ROA\A350\vc\f11w2\V53S3002920000
    V53S3261020000|M:\ROA\A350\vc\f11w3\V53S3261020000
    V53S1271620000|M:\ROA\A350\vc\f11w3\V53S1271620000
    V52S7158220000|M:\ROA\A350\vc\d11w1\V52S7158220000
    V53S3002920000|M:\ROA\A350\vc\f11w2\V53S3002920000
    Bref, tout se passe bien...
    (Et en ouvrant le fichier _unix.txt avec le bloc-note de windows qui ne reconnait que les \r\n, j'ai bien tout sur une seule ligne...)

  16. #16
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    J'imagine qu'il a plutôt un problème en compilant pour Linux ou alors j'ai pas tout compris

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Pas de soucis non plus sous unix... et j'ai envie de dire : c'est le comportement normal...

    Montre nous plutôt ton code ..

  18. #18
    Membre chevronné Avatar de Lavock
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    560
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 560
    Par défaut
    Un autre conversation vient de m'y faire penser, mais c'est vrai que la conversion est implicite... Du moment ou le fichier est ouvert en mode texte. N'aurais tu-pas connue cette bourde que de l'ouvrir en binaire?

  19. #19
    Membre émérite
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par défaut
    Je déterre mon vieu topic, ce soucis étant devenu à l'ordre du jour, il est temps pour moi d'essayer a nouveau de le regler.

    J'ai fait une petite avancée dejà, j'ai trouvé que l'erreur de la lecture des fichiers au format windows est due a l'appel préalable d'une méthode qui récupere le format du fichier, et qui prend en parametre une reference sur le istream en question...
    Sans l'appel a cette méthode, ça fonctionne tres bien en windows/linux formet de fin de ligne.

    Cette méthode est inspirée des sources de notepad++ :

    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
     
     
    int ReadFile::getFormat(std::istream& is) {
     
        //get character number
        is.seekg(0, std::ios::end);
        int size = is.tellg();
        is.seekg(0, std::ios_base::beg);
     
        char* pBuffer = new char[size + 1];
     
        is.read(pBuffer, size);
        is.seekg(0, std::ios_base::beg);
     
     
        //read BOM(Byte Order Marks)
        if ((pBuffer[0] == '\xFF' && pBuffer[0] == '\xFE') || (pBuffer[0] == '\xFE' && pBuffer[0] == '\xFF')) {
            is.seekg(2, std::ios_base::beg);
             return _UNICODE;
        }
        if ((int) pBuffer[0] == '\xEF' && (int) pBuffer[1] == '\xBB' && (int) pBuffer[2] == '\xBF') {
            is.seekg(3, std::ios_base::beg);
            return _UTF8;
        }
        if (pBuffer[0] == 0 && pBuffer[1] == 0 && pBuffer[2] == '\xFE' && pBuffer[3] == '\xFF') {
            is.seekg(4, std::ios_base::beg);
            return _UTF32;
        }
        if (pBuffer[0] == '\x2B' && pBuffer[1] == '\x2F' && pBuffer[2] == '\x76') {
            is.seekg(3, std::ios_base::beg);
            return _UTF7;
        } else {//no BOM
            if (IsUnicode(pBuffer, size, false, false) != 0) {
                return _UNICODE;
            }
            if (IsUTF8(pBuffer, size)) {
                return _UTF8;
            }
            if (strlen(pBuffer) >= (unsigned int) size) {
                return _ANSI;
            }
        }
     
        return _UNKNOW;
    }
    Je continue a creuser cette méthode... si jamais vous voyez des choses pas nettes...

    merci

  20. #20
    Membre émérite
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Par défaut
    Suite (et bientot fin j'espere) ici!

    Merci.

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

Discussions similaires

  1. [Windows]lecture des fichier lnk (raccourcis)
    Par Tiaps dans le forum API standards et tierces
    Réponses: 10
    Dernier message: 21/10/2009, 19h27
  2. Manipuler des fichiers de type Unix sous Windows
    Par hermes1983 dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 06/06/2009, 08h43
  3. fichier de boot unix écrasé par window
    Par lailalachir dans le forum Administration système
    Réponses: 3
    Dernier message: 03/01/2008, 10h23
  4. Lecture de fichiers crees sous Unix en VB6
    Par bzh_touch dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 30/03/2007, 17h46
  5. Réponses: 1
    Dernier message: 21/12/2006, 13h06

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