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 :

Entrée sortie fichiers


Sujet :

C

  1. #21
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Pouvez-vous me dire si c'est correct et si c'est portable s'il vous plait?
    Merci d'avance.

  2. #22
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Ceci n'est pas garanti par le standard C pour des fichiers texte:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
     fseek(fp,-2,SEEK_CUR);

  3. #23
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Comment faire alors?
    L'ouvrir en binaire? (ça change quelque chose??)

  4. #24
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Citation Envoyé par elishac Voir le message
    Comment faire alors?
    L'ouvrir en binaire? (ça change quelque chose??)
    Oui, ça change la gestion des fins de ligne d'un système d'exploitation à l'autre (ou plus précisément, ça la transfère sur tes épaules). Ce qui garantit le bon fonctionnement de fseek() avec SEEK_CUR.

  5. #25
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    ok, merci beaucoup pour la réponse. C'est dur à trouver tout seul, votre aide est précieuse.
    Il y a d'autres fautes dans ma fonction, à part ça?
    et sinon, comment est-ce que je teste le système d'exploitation ?

  6. #26
    Expert éminent
    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 : 38
    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
    Points : 8 389
    Points
    8 389
    Par défaut
    Oui c'est dur, et c'est pourquoi je t'ai fait remarquer que si le fichier contient une marque facilement reconnaissable en début de ligne, tu peux ouvrir le fichier en mode binaire et rechercher le début de la ligne après chaque fseek. Quelle est la structure d'une ligne de ton fichier log ?

    sinon, comment est-ce que je teste le système d'exploitation ?
    Un programme C est compilé donc le système d'exploitation ciblé tu le connais au moment même où tu compiles ... Si tu écris un programme portable, t'as aucune raison de connaître le système ciblé.

  7. #27
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Mon fichier ne commence pas ces lignes par ; ni par # ou quelque autre caractère spécifique, il commence juste ses lignes par une date.

    Pourriez-vous me donner un exemple où fseek ne marcherait pas bien pour un fichier texte, afin que je comprenne mieux?

  8. #28
    Expert éminent
    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 : 38
    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
    Points : 8 389
    Points
    8 389
    Par défaut
    Mon fichier ne commence pas ces lignes par ; ni par # ou quelque autre caractère spécifique, il commence juste ses lignes par une date.
    Dommage alors. Dans ce cas la seule option qui te reste, si tu veux que le programme soit portable, c'est d'ouvrir le fichier en mode texte et le parcourir séquentiellement (ligne par ligne).
    Pourriez-vous me donner un exemple où fseek ne marcherait pas bien pour un fichier texte, afin que je comprenne mieux?
    (...) Un flux de texte est organisé en lignes. En langage C, une ligne est une suite de caractères terminée par le caractère de fin de ligne (inclus) : '\n'. Malheureusement, ce n'est pas forcément le cas pour le système sous-jacent. Sous Windows par exemple, la marque de fin de ligne est par défaut la combinaison de deux caractères : CR (Carriage Return) et LF (Line Feed) soit '\r' et '\n' (notez bien que c'est CR/LF c'est-à-dire CR suivi de LF pas LF suivi de CR). Sous UNIX, c'est tout simplement '\n'. On se demande alors comment on va pouvoir lire ou écrire dans un fichier, à travers un flux de texte, de manière portable. Et bien c'est beaucoup plus simple que ce à quoi vous-vous attendiez : lorsqu'on effectue une opération d'entrée/sortie sur un flux de texte, les données seront lues/écrites de façon à ce qu'elles correspondent à la manière dont elles doivent être représentées et non caractère pour caractère. C'est-à-dire par exemple que, dans une implémentation où la fin de ligne est provoquée par la combinaison des caractères CR et LF, l'écriture de '\n' sur un flux de texte va provoquer l'écriture effective des caractères '\r' et '\n' dans le fichier associé. Sur un flux binaire les données sont lues ou écrites dans le fichier caractère pour caractère.

    (...) L'utilisation de fseek avec un flux de texte peut donner des résultats inattendus à cause du coup du '\n' ... Pour aller au n-ième caractère d'un fichier associé à un flux de texte (...), utilisez la méthode suivante : (...)
    Source : Manipulation des fichiers en C.

  9. #29
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Sequentiellement, ça veut dire utiliser n fois getc au lieu de fseek(fp,n,seek_cur) c'est ça?
    Je ne vois pas en quoi c'est plus portable...

  10. #30
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 590
    Points
    41 590
    Par défaut
    C'est plus portable parce que fseek() ne peut pas gérer les retours à la ligne (et leur traduction de \r\n à \n seul, qui change leur taille) de manière fiable.

    En mode binaire, tu supprimes la traduction, donc le changement de taille, donc fseek() redevient fiable.

  11. #31
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Désolé j'ai toujours un peu de mal. Il me faudrait peut-être un exemple. Pourriez-vous m'en donner un s'il vous plait?

  12. #32
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Prenons par exemple le fichier suivant (si vous avez un meilleur exemple, on peut prendre le votre) :

    -Quel serait le 4eme caractère de ce fichier ouvert en mode binaire et en mode texte, sous windows et sous linux?
    -Si on utilise 4 fois getc, qu'obtient-on en mode binaire et en mode texte, sous windows et sous linux?
    -Si on utilise fseek(fp,4,seek_set) qu'obtient-on en mode binaire et en mode texte, sous windows et sous linux?
    Je crois que les réponses à ces questions m'aideront à cerner le problème.
    Sachez pour l'instant que je m'embrouille complètement et que je ne saurais répondre avec certitude à aucune de ces questions (bien que j'aie lu les liens donnés), donc votre aide sera très utile. Merci d'avance

  13. #33
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 590
    Points
    41 590
    Par défaut
    '5e' serait plus parlant ici que 4e. Du moins, voici le contenu du fichier sous *n*x:
    Et sous DOS/Windows:
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    61 62 63 0D 0A 64 0D 0A

    Une lecture en mode texte avec juste des getc() est garantie donner ceci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    {'a', 'b', 'c', '\n', 'd', '\n'};
    Et c'est à peu près tout ce qui est garanti.

    En mode binaire, on aura le '\r' en plus sous Windows.
    Pour le fseek(), c'est justement la partie non-garantie, et c'est là que le bât blesse; je n'ai pas testé et je n'ai pas le temps. C'est pourquoi on ne doit utiliser que des valeurs retournées par ftell().

    D'ailleurs, c'est sans doute le résultat de ftell() qui sera le plus parlant: Si tu l'appelles après avoir fait quatre getc():
    • sous *n*x, tu auras sans doute 4
    • sous Windows, il est probable que tu aies 5 à la place (mais je n'ai pas testé).

  14. #34
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Ok, je pense que j'ai compris, merci de ces explications.
    Concrètement, quelles modifications dois-je donc apporter à mon programme pour qu'il devienne portable?
    La solution serait-elle de l'ouvrir en binaire, et de créer une autre fonction (qui provoque un aller à la ligne sur un fichier tmp et vérifie si c'est \n ou \r\n) pour identifier le type de système, et créer une constante qui vaut soit \n soit \r\n ?

  15. #35
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 590
    Points
    41 590
    Par défaut
    Ça dépend ce que tu cherches à faire.
    Si tu cherches juste à remonter X lignes plus haut, tu peux rester en texte: il te suffit de mémoriser les valeurs retournées par ftell() pour les X dernières lignes...

  16. #36
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Je ne cherche pas à remonter x lignes plus haut, je cherche à faire pointer fp sur le début de la ligne précédente. C'est le but de la fonction... (je n'ai pas vraiment compris la question en fait).

  17. #37
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 382
    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 382
    Points : 41 590
    Points
    41 590
    Par défaut
    C'est simple alors:
    • Début de la ligne courante: Un seul retour de ftell() à mémoriser, le dernier (en appellant ftell() après chaque getc() qui aurait retourné \n).
    • Début de la ligne précédente: Deux retours de ftell() à mémoriser (les deux derniers).

  18. #38
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    Ce que vous êtes en train de dire, c'est qu'il faut lire le fichier en entier pour savoir quelle est l'emplacement de la ligne précédente?
    Car c'est précisément ce que je veux éviter (cette fonction fait partie d'une fonction plus globale ayant pour but d'accéder à une date précise d'un log très long sans avoir à le parcourir en entier, en procédant par dichotomie)

  19. #39
    Membre confirmé 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
    Points : 633
    Points
    633
    Par défaut
    non, a chaque nouvelle ligne, tu retiens le retour de ftell dans une file de un ou deux élément (pas bien compris là ou tu dois "revenir"). Quand tu aura trouvé ce que tu veux, tu sautes à la ligne voulu depuis le début du fichier.

  20. #40
    Inactif
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    136
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 136
    Points : 25
    Points
    25
    Par défaut
    "a chaque nouvelle ligne", ça veut dire qu'il faut parcourir le fichier en entier, non?

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/04/2012, 22h30
  2. Réponses: 15
    Dernier message: 01/11/2008, 16h57
  3. Entrée / sortie dans un fichier binaire
    Par mejrs dans le forum Débuter
    Réponses: 1
    Dernier message: 24/05/2008, 17h48
  4. Réponses: 17
    Dernier message: 07/05/2008, 11h16
  5. Réponses: 11
    Dernier message: 13/10/2004, 01h58

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