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

Bibliothèque standard C Discussion :

Gestion d'un fichier à l'aide de fseek ?


Sujet :

Bibliothèque standard C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 42
    Points : 25
    Points
    25
    Par défaut Gestion d'un fichier à l'aide de fseek ?
    Bonjour,

    Je cherche à gérer un fichier comme s'il s'agissait d'un buffer circulaire, dont la taille des slots et le nombre de slots seraient fixés, et dans lequel j'irai écrire une chaîne de caractère de taille variable dont la longueur maximale ne dépasserait pas la taille d'un slot.

    Pour plus de compréhension, il faut imaginer que le fichier pourra par exemple stocker au maximum 10 messages de 512 caractères maximum sauf que lorsque j'enregistre un message, sa taille est variable.

    De plus, étant donné qu'il s'agit d'un "buffer circulaire", je ne veux pas écraser mes messages précédents lorsque je recommence une écriture depuis le début du fichier (arrivé à la fin du buffer).

    Pour gérer cela, j'ai essayé d'utiliser la fonction fseek en me disant qu'elle pourrait me permettre de me déplacer de slot en slot (de 512 carac. max chacun) à l'intérieur de mon fichier. Cependant, en pratique, la fonction ne permet apparemment pas d'écrire au delà du caractère EOF d'après ce que j'ai pu voir sur certains sites.

    C'est-à-dire que si j'ai un 1er message de taille 256, que je l'enregistre au début de mon fichier et que pour le suivant, de taille 412, j'essaie de l'enregistrer à la position 512 (taille d'un slot) via l'utilisation de la fonction fseek, je n'ai pas d'erreur mais quelque-chose se passe mal.

    En effet, quand j'affiche le contenu de mon fichier, je vois des caractères bizarres à la place de mon 1er message alors que le 2ème est correcte.

    Avez-vous une idée qui pourrait m'aider ?

    Merci,

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    Citation Envoyé par Akutabi Voir le message
    à la place de mon 1er message alors que le 2ème est correcte.

    Avez-vous une idée qui pourrait m'aider ?

    Merci,
    vous devez toujours écrire des blocs de la taille de vos slots pas de vos messages…

    ou

    vous initialisez un fichier "vide" (des zéros) de N x taille des slots…
    au début de votre programme…

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 42
    Points : 25
    Points
    25
    Par défaut
    Malheureusement, je ne pense pas pouvoir appliquer l'une ou l'autre de ces solutions... Du coup, je vais voir ce que je peux faire. Merci quand même.

  4. #4
    Membre du Club
    Inscrit en
    Juin 2008
    Messages
    85
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 85
    Points : 68
    Points
    68
    Par défaut
    Salut,

    Tu ne peux pas mettre un caractères de remplissage (pour remplir le slot et ainsi déplacer ton EOF au prochain slot)?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 42
    Points : 25
    Points
    25
    Par défaut
    Le problème est que ça risquerait d'être une solution assez lourde. Si j'ai un message de taille 100 et que ma taille max est de 512, je dois créer une boucle qui va ajouter 412 caractères de remplissage...je suis pas sûr que ça vaille vraiment le coup. Donc faut voir...

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    Citation Envoyé par Akutabi Voir le message
    Le problème est que ça risquerait d'être une solution assez lourde. Si j'ai un message de taille 100 et que ma taille max est de 512, je dois créer une boucle qui va ajouter 412 caractères de remplissage...je suis pas sûr que ça vaille vraiment le coup. Donc faut voir...
    ce remplissage : vous ne devez le faire qu'une fois au début du programme…

    si vos messages sont des strings C ('\0' terminated) et que vous assurez que ce '\0' soit bien copié dans le buffer, la relecture se fera sans problème…
    même si esthétiquement il y aura de temps en temps du garbage derrière ce '\0' …

    (et pour ce qui est d'une boucle : la librairie C standard ne manque pas de fonctions pour remplir une zone mémoire avec une valeur…)

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 42
    Points : 25
    Points
    25
    Par défaut
    En fait, j'ai presque réussi à gérer mon fichier comme je le souhaitai en l'ouvrant une seule fois avec fopen (option "w"), et en réalisant des écritures au fur et à mesure que mes messages arrivent grâce à fprintf ainsi que fseek pour déplacer l'index d'un slot à un autre.

    En fait, avant d'écrire un nouveau slot, je "réserve" toujours dans le fichier une zone ayant une taille égale à la taille maximale de mon message. Cette zone est constituée uniquement de caractères SPACE qui sont ensuite écrasés par mon message.

    Par contre, j'ai un petit souci que j'aimerai bien régler. Lorsque je fais appel à la fonction fprintf, cette dernière n'écrit réellement le message reçu dans le fichier qu'après avoir été appelée de nouveau lors de la réception d'un nouveau message.

    Un fclose permettrait de régler ce problème et d'écrire dans le fichier le message mémorisé par fprintf. Cependant, j'ai besoin d'éviter de refermer à chaque fois le flux après un appel à fprintf.

    Du coup, je vois pas comment forcer l'écriture du message à chaque réception (chaque appel à fprintf)... une idée ?

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    Citation Envoyé par Akutabi Voir le message

    Du coup, je vois pas comment forcer l'écriture du message à chaque réception (chaque appel à fprintf)... une idée ?
    fflush

  9. #9
    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 518
    Points
    41 518
    Par défaut
    Attends: Tu joues avec des fseek() et compagnie, des enregistrements à taille fixe etc.... sur un fichier texte?
    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.

  10. #10
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Attends: Tu joues avec des fseek() et compagnie, des enregistrements à taille fixe etc.... sur un fichier texte?
    oui, ça marche aussi... A condition que les "enregistrements" et/ou ta manière d'écrire soit correcte... et tes calculs de ftell, fseek, etc etc.. c'est juste que de temps en temps tu as un '\r' ou un '\n", ou même un '\0'.. Mais un fichier est un fichier...
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  11. #11
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    C'est hors norme : pour les fichiers texte, l'offset doit être soit 0 soit une valeur obtenue précédemment par ftell
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  12. #12
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    Citation Envoyé par diogene Voir le message
    C'est hors norme : pour les fichiers texte, l'offset doit être soit 0 soit une valeur obtenue précédemment par ftell
    "The fseek() function shall allow the file-position indicator to be set beyond the end of existing data in the file. If data is later written at this point, subsequent reads of data in the gap shall return bytes with the value 0 until data is actually written into the gap."

    fichier "texte" ou pas…

  13. #13
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    A chacun ses sources :


    Norme n1256

    7.19.9.2 The fseek function
    ....
    4 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.
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  14. #14
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    oui et ???

    Il est bien dit "a successfull call to ftell" , non ?? et pas forcément 0..

    Qu'est-ce qui t'empêche de calculer correctement tes offsets, de stocker tes ftell, etc etc, et en même temps de faire des fgets ou des getc ??

    J'ai fait toute une BD opérationnelle temps réel avec des fichiers textes (lue en temps réel, et écrite au fur et à mesure également)...

    exemple du fichier :

    20081208235900001 +42.5143 +1.1281 112 -20 0 1 2

    Toujours même longueur de ligne ("enregistrement"). Ecriture au fur et à mesure dans le fichier. Lecture par positionnement dichotomique (fseek, SEEK_SET, valeur de l'offset), avec getc pour trouver début de ligne, puis fgets et ftell pour stocker la position.. So what ???
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  15. #15
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    L'écriture dans un fichier texte peut tronquer le fichier a la position d'écriture. Ce n'est pas le cas pour un fichier binaire.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  16. #16
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    L'écriture dans un fichier texte peut tronquer le fichier a la position d'écriture. Ce n'est pas le cas pour un fichier binaire.
    toute l'ambiguité des discussions vient de l'expression "fichier texte" …

    ce n'est pas parce que l'on met des messages lisibles par un humain que le fichier est un fichier texte au sens POSIX habituellement admis :

    "A file that contains characters organized into one or more lines. The lines do not contain NUL characters and none can exceed {LINE_MAX} bytes in length, including the <newline>. Although IEEE Std 1003.1-2001 does not distinguish between text files and binary files (see the ISO C standard), many utilities only produce predictable or meaningful output when operating on text files. The standard utilities that have such restrictions always specify "text files" in their STDIN or INPUT FILES sections"

    A partir du moment où il n'y aurait pas de '\n' à la fin des messages mais un '\0' (suivi du padding …) ce fichier de messages ne devrait pas être considéré comme un "text file"…
    et en conséquence il devrait idéalement être manipulé en mode binaire : "wb" ou "rb"…

    ouvrir le fichier en mode texte (sans le "b") alors qu'il contiendrait des NUL bytes ne peut qu'attirer des ennuis… avec en plus les restrictions liées à fseek dans ce mode…

  17. #17
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    toute l'ambiguité des discussions vient de l'expression "fichier texte" …
    Dans cette discussion, il n'y a qu'une interpretation possible: absence de b dans le mode d'ouverture.

    ce n'est pas parce que l'on met des messages lisibles par un humain que le fichier est un fichier texte au sens POSIX habituellement admis :
    Pour POSIX, la difference entre fichier texte et binaire est nulle pour un programme, que tu l'ouvres avec ou sans "b", le comportement est exactement le meme (c'est une garantie supplementaire que donne POSIX par rapport a la norme C, comme le fait que CHAR_BIT vaut 8 et d'autres choses encore). La notion de fichier texte intervient comme contrainte pour les fichiers fournis aux "utilitaires", certains d'entre eux ont un resultat non specifie si les fichiers ne sont pas des fichiers textes. Tu cites d'ailleurs le texte qui le dit.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  18. #18
    Expert éminent sénior

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    bref, sur le problème posé, il n'y a aucun problème ..

    (Jean-Marc, si tu veux, je peux te faire parvenir un test avec le fichier cité ci-dessus et les 2 serveurs : un qui écrit dedans et un qui lit... Et tu verras toi-même)
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  19. #19
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Dans cette discussion, il n'y a qu'une interpretation possible: absence de b dans le mode d'ouverture.

    Pour POSIX, la difference entre fichier texte et binaire est nulle pour un programme, que tu l'ouvres avec ou sans "b", le comportement est exactement le meme (c'est une garantie supplementaire que donne POSIX par rapport a la norme C, comme le fait que CHAR_BIT vaut 8 et d'autres choses encore). La notion de fichier texte intervient comme contrainte pour les fichiers fournis aux "utilitaires", certains d'entre eux ont un resultat non specifie si les fichiers ne sont pas des fichiers textes. Tu cites d'ailleurs le texte qui le dit.
    avec ou sans le "b", le comportement de fseek n'est justement pas le même…

    et que la discussion aurait été plus courte, si l'on avait répondu dès le début :
    "ouvrez le fichier en mode binaire …".

  20. #20
    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 518
    Points
    41 518
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    avec ou sans le "b", le comportement de fseek n'est justement pas le même…
    Si j'ai bien compris, Jean-Marc vient de dire que le comportement était garanti identique sous POSIX.

    Le problème, c'est que Akutabi n'a jamais dit être sous un quelconque système POSIX... (du moins, pas dans ce thread).
    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.

Discussions similaires

  1. Aide pour une gestion d'un fichier d'adresse
    Par Shtrakeur dans le forum Général Python
    Réponses: 3
    Dernier message: 29/10/2011, 10h19
  2. Gestion des Fichiers d'aide
    Par phdnet dans le forum W4 Express
    Réponses: 1
    Dernier message: 04/06/2007, 09h39
  3. Gestion OLE/COM pour Excel + Fichier d'aide
    Par MelkInarian dans le forum Delphi
    Réponses: 1
    Dernier message: 25/02/2007, 16h21
  4. Besoin du fichier d'aide du SDK DirectX7 (pour DirectDraw)
    Par Magus (Dave) dans le forum DirectX
    Réponses: 5
    Dernier message: 02/10/2002, 13h08
  5. appel de fichier d'Aide
    Par Atrebate62 dans le forum Composants VCL
    Réponses: 5
    Dernier message: 24/09/2002, 14h13

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