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 :

Fichier en langage c


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    193
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 193
    Par défaut Fichier en langage c
    Bonjour,

    J'avais une question à vous poser concernant la lecture d'un fichier: est ce possible d'accéder à la ligne 16 par exemple d'un fichier sans que je lise les 15 premières lignes?
    Merci...

  2. #2
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Question récurrente, c'est impossible.

  3. #3
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Pour compléter la réponse de Melem, on peut s'en sortir à coup de fseek() si les lignes ont une taille fixe ou en gérant à la main un index de ligne.
    Mais c'est assez complexe pour un gain qui est, sauf cas particulier, plutôt faible si ce n'est nul.

  4. #4
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Citation Envoyé par gl
    Pour compléter la réponse de Melem, on peut s'en sortir à coup de fseek() si les lignes ont une taille fixe
    Que les lignes aient une taille fixe ne change rien. La doc de int fseek(FILE *stream, long int offset, int whence) dit bien :
    For a text stream, either offset shall be zero, or offset shall be a value returned by an earlier successful call to the ftell function on a stream associated with the same file and whence shall be SEEK_SET.
    Citation Envoyé par gl
    ou en gérant à la main un index de ligne.
    Mais pour créer la table des index il faut avoir déjà lu toutes les lignes.

  5. #5
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Melem Voir le message
    Que les lignes aient une taille fixe ne change rien.
    Oups ! Effectivement j'ai oublié de mettre en avant les habituelles restrictions de cette méthode.
    Le fonctionnement n'est en effet pas garantie par le standard et n'est donc pas 100% portable. Bien qu'en pratique cela fonctionne plutôt bien sur les plate-formes que je connais (mais le code n'est pas portable).

    Citation Envoyé par Melem Voir le message
    Mais pour créer la table des index il faut avoir déjà lu toutes les lignes.
    Il est également possible de le faire lors de l'écriture du fichier. Mais surtout cela peut être fait une fois pour toute lors de la première lecture si le fichier est souvent lu mais jamais modifié.
    Dans tous les cas ce n'est utilisable qu'en interne (i.e. pas question de transférer le fichier texte et l'index dans une autre environnement en espérant que ça marche).

    Ceci étant, sauf cas particuliers, c'est assez inutile comme pratique.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    bah..

    La seule non-portabilité est le `\n' par rapport au '\n\r"...

    Donc je trouve que la norme "abuse"...

  7. #7
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    bah..

    La seule non-portabilité est le '\n' par rapport au '\n\r'...

    Donc je trouve que la norme "abuse"...
    Déjà c'est quasi inexistant des systèmes qui utilisent \n\r comme marqueur de fin de ligne. Tu voulais sûrement parler de la séquence \r\n, utilisée sous DOS et Windows entre autres, mais c'est vrai que cela ne change pas grand-chose à ce que tu as dit.

    Maintenant en parlant d'abus.

    La philosophie du mode texte c'est que certaines séquences d'octets peuvent avoir une signification spéciale. La marque de fin de ligne est un exemple bien connu mais il y en a d'autres, pour ne citer que le caractère de code 26 (Ctrl + Z) qui est interprété comme le marqueur de fin de fichier texte sous Windows par exemple (mais un fichier texte peut ne pas comporter ce caractère). Donc si tu utilises fseek sur un fichier texte ouvert en lecture et contenant le caractère Ctrl + Z (suppose par exemple que ce caractère apparaisse en plein milieu du fichier), tu pourrais ne pas avoir les mêmes résultats sous Windows puis sous Linux par exemple. => Ton programme n'est pas portable.

    Même au sein d'un et un seul système (prenons Windows par exemple) l'effet d'un fseek avec des valeurs autres que 0 ou une valeur retournée par ftell pour offset et SEEK_SET pour whence sur un fichier texte n'est pas toujours évident. Si ton fichier est encodé en UTF-8 par exemple et que tu l'ouvres en mode texte UTF-8. Selon toi, un fseek sur ce fichier devrait te positionner à l'octet d'index offset ou au caractère d'index offset ? Même MSDN ne répond pas à cela :
    The only fseek operations guaranteed to work on streams opened in text mode are:

    * Seeking with an offset of 0 relative to any of the origin values.
    * Seeking from the beginning of the file with an offset value returned from a call to ftell.
    C'est la même spécification que celle dans la norme du C. Il ne faut pas chercher à compliquer.

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Melem Voir le message
    La philosophie du mode texte c'est que certaines séquences d'octets peuvent avoir une signification spéciale. La marque de fin de ligne est un exemple bien connu mais il y en a d'autres, pour ne citer que le caractère de code 26 (Ctrl + Z) qui est interprété comme le marqueur de fin de fichier texte sous Windows par exemple (mais un fichier texte peut ne pas comporter ce caractère). Donc si tu utilises fseek sur un fichier texte ouvert en lecture et contenant le caractère Ctrl + Z (suppose par exemple que ce caractère apparaisse en plein milieu du fichier), tu pourrais ne pas avoir les mêmes résultats sous Windows puis sous Linux par exemple. => Ton programme n'est pas portable.

    Même au sein d'un et un seul système (prenons Windows par exemple) l'effet d'un fseek avec des valeurs autres que 0 ou une valeur retournée par ftell pour offset et SEEK_SET pour whence sur un fichier texte n'est pas toujours évident. Si ton fichier est encodé en un fgets, même sous Windows le fait de tomber sur " UTF-8 par exemple et que tu l'ouvres en mode texte UTF-8. Selon toi, un fseek sur ce fichier devrait te positionner à l'octet d'index offset ou au caractère d'index offset ? Même MSDN ne répond pas à cela :
    C'est la même spécification que celle dans la norme du C. Il ne faut pas chercher à compliquer.
    Euh....

    Quand on fait fopen ( fichier, "r")

    puis qu'on fait fseek, en quoi est-ce qu'on se réfère à UTF8 ou à CTRL-Z ??

    Si on fait un getc, ou fgets, le fait de tomber sur CTRL-Z (ou par exemple CTRL-M si on lit un fichier Win sous Unix) n'empêche en rien la lecture...


    C'est là que je comprend pas...

    Que l'interpétation des séquences soient faussée, je veux bien... Mais ça c'est au lecteur de le savoir..

    Mais la lecture du fichier du début jusqu'à EOF, ou le déplacement d'un certain nombre d'octets m'apparaît comme totalement indépendant...

    Ou alors je manque quelque chose...


    PS: et là je ne parle pas de philosophie d'un fichier texte, mais de ce que dit la norme à propos de fseek ... qui normalement est un déplacement en octets.. ou tout au moins en unités du filesystem..

  9. #9
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Quand on fait fopen ( fichier, "r")

    puis qu'on fait fseek, en quoi est-ce qu'on se réfère à UTF8
    Il existe des extensions non standard (je l'ai bien précisé dans mon précédent message) aussi bien sous Windows que sous d'autres systèmes qui permettent d'indiquer le codage utilisé par le fichier texte. Dans UTF-8 les codes n'ayant pas tous la même longueur en bits, un getc peut te retourner un caractère 8 bits alors qu'il a pu faire avancer le caractère de 16 et non de 8 bits par exemple.

    ou à CTRL-Z ??
    Alors je continue :
    Also in text mode, CTRL+Z is interpreted as an end-of-file character on input. In files opened for reading/writing, fopen and all related routines check for a CTRL+Z at the end of the file and remove it if possible. This is done because using fseek and ftell to move within a file that ends with a CTRL+Z may cause fseek to behave improperly near the end of the file.

  10. #10
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Melem Voir le message
    Il existe des extensions non standard (je l'ai bien précisé dans mon précédent message) aussi bien sous Windows que sous d'autres systèmes qui permettent d'indiquer le codage utilisé par le fichier texte. Dans UTF-8 les codes n'ayant pas tous la même longueur en bits, un getc peut te retourner un caractère 8 bits alors qu'il a pu faire avancer le caractère de 16 et non de 8 bits par exemple.
    ok. Mais ça ça a à voir aec le filesystem.. Tu auras la même chose avec stat ou autres..

    Mais pour la 2ième partie :


    Also in text mode, CTRL+Z is interpreted as an end-of-file character on input. In files opened for reading/writing, fopen and all related routines check for a CTRL+Z at the end of the file and remove it if possible. This is done because using fseek and ftell to move within a file that ends with a CTRL+Z may cause fseek to behave improperly near the end of the file.
    DONC une fois le fichier ouvert avec fopen, on devrait pouvoir utiliser fseek


    Maintenant, ça c'est pour rw.. Pour r seulement, je ne vois pas trop..

  11. #11
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    DONC une fois le fichier ouvert avec fopen, on devrait pouvoir utiliser fseek
    Non : DONC une fois le fichier ouvert avec fopen en mode lecture ET écriture, comme tu l'as précisé plus bas, le Ctrl + Z est supprimé s'il est présent, et s'il peut être supprimé. Ensuite, on peut évidemment utiliser fseek comme on le peut sur n'importe quel fichier texte, contenant un Ctrl + Z ou pas, MAIS en respectant les restrictions concernant cette utilisation de fseek sur un fichier texte. Ces restrictions rendent impossible d'aller à une ligne n d'un fichier texte sans avoir déjà passé au moins une fois par toutes les lignes précédentes, pour en revenir au sujet.

    Maintenant, ça c'est pour rw.. Pour r seulement, je ne vois pas trop..
    Pour r seulement bin tu fais fgetc par exemple et que le caractère lu est Ctrl + Z, fgetc retournera EOF, pas Ctrl + Z.

  12. #12
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Melem Voir le message
    Ces restrictions rendent impossible d'aller à une ligne n d'un fichier texte sans avoir déjà passé au moins une fois par toutes les lignes précédentes, pour en revenir au sujet.
    Pour arriver à la ligne N oui..

    Mais ce que je veux dire, c'est quand dans le genre de cas comme exposé par un posteur ailleurs, tu peux faire de la dichotomie et arriver à la ligne voulue sans être passé par toutes les lignes précédentes.. (par exemple si tu cherches une date dans un fichier où chaque ligne commence par une date)

    C'est pour cela que je trouve que la norme "abuse"...

  13. #13
    Expert confirmé
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Par défaut
    Tu fais apparemment référence à cette discussion.

    tu peux (...) arriver à la ligne voulue sans être passé par toutes les lignes précédentes
    Je répète que c'est impossible en C standard. Dans la discussion que tu cites, le fichier est ouvert en mode binaire, c'est pourquoi on peut faire des fseek pour aller n'importe où sans être déjà passé par tous les caractères précédents. En tout cas le programme au centre de cette discussion n'est elle non plus pas portable ...

Discussions similaires

  1. Normales et fichier md5 (langage C)
    Par Ninqueelen dans le forum OpenGL
    Réponses: 6
    Dernier message: 15/10/2013, 19h13
  2. Ouvrir des fichiers en langage R
    Par riadmims dans le forum R
    Réponses: 3
    Dernier message: 24/05/2012, 10h23
  3. fichier texte (langage C)
    Par noussa309 dans le forum Débuter
    Réponses: 3
    Dernier message: 21/10/2011, 17h10
  4. [Traitement de fichier] Quel langage choisir?
    Par frutix dans le forum Langages de programmation
    Réponses: 3
    Dernier message: 06/02/2010, 16h54
  5. Fichier en langage C
    Par bsangoku dans le forum Débuter
    Réponses: 5
    Dernier message: 23/12/2009, 12h07

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