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 :

Obtenir le caractère à une position donnée dans un fichier


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2010
    Messages : 119
    Par défaut Obtenir le caractère à une position donnée dans un fichier
    Bonjour à tous,

    Je début dans le traitement de fichier en C.
    Je cherche à créer une application capable de m'afficher sur la sortie standard les n dernières lignes d'un fichier passé en paramètre (n étant aussi passé en paramètre).

    J'envisage d'utiliser l'algorithme suivant :
    - Me placer à la fin du fichier.
    - Lire caractere par caractere en remontant vers le début du fichier, et stocker les caractere dans un tampon.
    - Si je rencontre un '\n', j'affiche le contenu de mon tampon.
    ===> je recommence n fois.

    Et se pose un problème pour moi :
    Une fois que je connais la taille en octets, et donc le nombre de caractères de mon fichier, comment obtenir le dernier caractère, puis le précédent... etc.

    Merci en tout cas de votre aide!

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Alba.1337 Voir le message
    Bonjour à tous,

    Je début dans le traitement de fichier en C.
    Je cherche à créer une application capable de m'afficher sur la sortie standard les n dernières lignes d'un fichier passé en paramètre (n étant aussi passé en paramètre).

    Et se pose un problème pour moi :
    Une fois que je connais la taille en octets, et donc le nombre de caractères de mon fichier, comment obtenir le dernier caractère, puis le précédent... etc.

    Merci en tout cas de votre aide!
    Salut

    Pour un fichier ouvert avec fopen(), alors tu peux utiliser fseek() qui te positionne dans le fichier
    fseek(fichier, SEEK_SET, x) => te place en position x
    fseek(fichier, SEEK_CUR, x) => te fait avancer de x caractères par rapport à ta position courante
    fseek(fichier, SEEK_END, x) => te place x caractères avant la fin de fichier

    Pour un fichier ouvert avec open() alors faut utiliser lseek() avec les mêmes critères...

    Citation Envoyé par Alba.1337 Voir le message
    J'envisage d'utiliser l'algorithme suivant :
    - Me placer à la fin du fichier.
    - Lire caractere par caractere en remontant vers le début du fichier, et stocker les caractere dans un tampon.
    - Si je rencontre un '\n', j'affiche le contenu de mon tampon.
    ===> je recommence n fois.
    Plus simple: tu parcours ton fichier en comptant les '\n' ce qui te donne le nb de lignes. Tu stockes la position de chaque début de ligne dans un tampon.
    Quand tu connais le nb de lignes tu calcules la ligne "l" sur laquelle il te faut aller pour avoir les "n" dernières lignes puis tu t'y place via fseek() car tu connais sa position (prise dans le tampon) et tu lis jusqu'à la fin...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2010
    Messages : 119
    Par défaut
    En effet le 2e algorithme est pas mal... Je place donc dans un tableau, un pointeur sur chaque caractère consécutif à un '\n' et le premier caractère du fichier... Et il me suffit, quand je connais le nombre de lignes, de parcourir l'espace mémoire à partir de la ligne concernée, jusqu'à la fin du fichier?

    Mais pour en revenir à mon algo, quand j'ai placé ma tête de lecture avec fseek, comment lire le caractère sous la tête? read?

    Excusez moi, je débute vraiment en traitement de fichiers...

    Merci!

  4. #4
    Membre chevronné
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2012
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2012
    Messages : 190
    Par défaut
    salut !
    dans http://publications.gbdirect.co.uk/c_book/ il y a un chapitre 9 Libraries où tu trouveras une brève description de chaque fonction d'un standard ancien qui permet de faire rapidement le tour de tout ce qu'on peut faire sans difficulté. dans ton cas précis :
    9.11. Formatted I/O
    9.12. Character I/O
    A+

    PS il existe une version pdf de ce manuel (google ...).

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    J'allais dire : regardons tail... Mais vu la taille du fichier source, ce n'est peut-être pas une bonne idée

  6. #6
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2010
    Messages : 119
    Par défaut
    Bah le but de ce tp, est de faire une version simplifiée de tail

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Alba.1337 Voir le message
    En effet le 2e algorithme est pas mal... Je place donc dans un tableau, un pointeur sur chaque caractère consécutif à un '\n'
    Tu n'as pas bien réfléchi.
    Les caractères lus du fichier ne sont pas en mémoire. Donc stocker un "pointeur" ne te servira à rien.
    C'est les positions des lignes qu'il te faut stocker...

    Citation Envoyé par Alba.1337 Voir le message
    et le premier caractère du fichier...
    As-tu vraiment besoin de stocker la position de la première ligne du fichier ???
    Citation Envoyé par Alba.1337 Voir le message
    Et il me suffit, quand je connais le nombre de lignes, de parcourir l'espace mémoire à partir de la ligne concernée, jusqu'à la fin du fichier?
    Ben non, ce n'est pas ce que j'ai écrit. Les lignes lues ne sont pas en mémoire...

    Citation Envoyé par Alba.1337 Voir le message
    Mais pour en revenir à mon algo, quand j'ai placé ma tête de lecture avec fseek, comment lire le caractère sous la tête? read?
    read() ne marche que pour les fichiers ouverts avec open(). Pour fopen() alors tu as le choix entre
    fgetc() => 1 caractère
    fgets() => 1 ligne entière
    fread() => 1 bloc de "n" éléments, chaque élément étant de la taille de "x" octets
    fscanf() => 1 entrée formatée

    Citation Envoyé par Alba.1337 Voir le message
    Bon alors j'ai fait quelque chose...
    Ca compile, c'est déjà pas mal, mais doit y avoir une boucle infinie quelque part. De plus, je doute vraiment que ca puisse marcher, ne sachant pas utiliser "read" etc... Si quelqu'un comprends la manière dont je veux procéder, je suis à l'écoute de tout conseil.
    Le problème de open()+read(), c'est qu'il n'y a aucune notion de "ligne" dans ces outils. read() te lit "n" octets
    C'est donc à toi ensuite de chercher les '\n' pour découper ces octets en "lignes" identifiables. Au pire tu peux lire tes octets un à un pour construire ta ligne caractère par caractère mais c'est pas ce qu'il y a de plus fin...

    Si t'es libre de tes choix, je te conseillerais plutôt fopen() + fgets() plus dédiés aux fichiers textes. Car fgets() lit "n" octets mais s'arrête s'il rencontre un '\n' => il te donne donc une ligne complète...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2010
    Messages : 119
    Par défaut
    Re-bonjour, et merci du temps que vous prenez pour m'aider.

    En fait, ce que je pensais faire moi, c'est lire mon fichier caractere par caractere à partir de la fin, et stocker ces caracteres dans mon tampon. Comme ca a chaque '\n', je peux lire mon tampon en partant de la fin de celui-ci, pour avoir ma chaine dans l'ordre.

    Sve@r, ta technique me parait beaucoup plus naturelle, surtout grace à fgets() qui peut récupérer directement une ligne...
    Mon problème, c'est que je vois bien comment trouver la position d'un '\n' (avec une boucle while et un compteur?), mais une fois que j'ai un tableau avec les positions des débuts de lignes, comment obtenir le caractère à la position donnée? N'y a t'il pas de fonction directe? Suis-je contraint d'utiliser une boucle?

    Et puisque fgets() me donne directement une ligne, ne puis-je pas simplement compter le nombre de ligne de mon fichier, puis re-parcourir mon fichier en n'affichant que les lignes demandés?

    Merci encore.


    PS : j'avais trouvé la variable SC_LINE_MAX pour la longueur maximale d'une ligne, ce qui me permettait d'initialisé mon tampon. Mais y a t-il un nombre maximum de lignes dans un tableau? (je demande ca pour la creation du tableau de positions).

  9. #9
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Alba.1337 Voir le message
    En fait, ce que je pensais faire moi, c'est lire mon fichier caractere par caractere à partir de la fin, et stocker ces caracteres dans mon tampon. Comme ca a chaque '\n', je peux lire mon tampon en partant de la fin de celui-ci, pour avoir ma chaine dans l'ordre.
    Oui si tu veux.

    Citation Envoyé par Alba.1337 Voir le message
    Sve@r, ta technique me parait beaucoup plus naturelle, surtout grace à fgets() qui peut récupérer directement une ligne...
    Mon problème, c'est que je vois bien comment trouver la position d'un '\n' (avec une boucle while et un compteur?), mais une fois que j'ai un tableau avec les positions des débuts de lignes, comment obtenir le caractère à la position donnée?
    Ton sujet n'est pas d'avoir le "caractère à la position donnée" mais d'afficher les "n" dernières lignes. Donc si ton fichier a 15 lignes et que tu dois afficher les 4 dernières ben tu vas à la position où débute la ligne 12 et tu affiches tout le reste du fichier...

    Citation Envoyé par Alba.1337 Voir le message
    N'y a t'il pas de fonction directe? Suis-je contraint d'utiliser une boucle?
    fseek() + boucle sur fgets()

    Citation Envoyé par Alba.1337 Voir le message
    Et puisque fgets() me donne directement une ligne, ne puis-je pas simplement compter le nombre de ligne de mon fichier, puis re-parcourir mon fichier en n'affichant que les lignes demandés?
    Oui ça marche aussi....

    Citation Envoyé par Alba.1337 Voir le message
    PS : j'avais trouvé la variable SC_LINE_MAX pour la longueur maximale d'une ligne, ce qui me permettait d'initialisé mon tampon. Mais y a t-il un nombre maximum de lignes dans un tableau? (je demande ca pour la creation du tableau de positions).
    Non. Cela fait partie du domaine des tableaux de taille inconnue qui absorbent des données au fur et à mesure. On peut le résoudre via realloc()
    1) tu places un pointeur à NULL, un indice à 0 et une taille à 0
    2) quand tu veux stocker un élément, tu regardes si l'indice a atteint la taille
    3) si c'est le cas alors tu incrémentes la taille de N et tu realloues ton pointeur de "taille" éléments (quand il est à NULL le realloc est automatiquement converti en malloc)
    4) tu stockes l'élément dans la case "indice" et tu incrémentes l'indice
    Mais c'est peut-être pas encore au programme de ton cours. A mon avis, ta proposition de compter puis de revenir et d'afficher est pas mal. Surtout que comme il faudra compter 2 fois (une fois pour connaitre le nb de lignes et une seconde fois pour se placer sur la ligne qui va bien), tu peux dédier ce travail à une fonction dédiée (à laquelle tu passes une info disant s'il faut tout compter ou compter seulement "n" lignes)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 02/12/2014, 22h25
  2. Remplacement d'un caractère à une position donnée
    Par erustika dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 24/10/2011, 16h35
  3. Réponses: 0
    Dernier message: 23/12/2009, 10h14
  4. Ecriture à une position donné dans un fichier
    Par xarius dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 29/05/2006, 16h05
  5. Inserer du texte à une position donnée dans un Memo
    Par bassim dans le forum Composants VCL
    Réponses: 2
    Dernier message: 23/11/2005, 17h45

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