fichier "Texte-Tabulé"

tabliertablier Membre
20:50 modifié dans API AppKit #1
Je souhaite ouvrir un fichier "texte-tabulé" (ou csv) et récupérer séquentiellement les textes individuels en contrôlant les changements de lignes.
Je n'ai rien trouvé de mieux que d'en faire un NSSstring et d'analyser le résultat caractère par caractère (recherche des fins de lignes et des tabulations).
:( ça marche, mais ça ne me parait lourd et peu élégant!

J'ai jeté un oe“il sur NSUnarchiver et sur NSData, mais je ne vois pas trop comment utiliser cela.
Quelle serait la méthode la plus simple pour arriver à  mes fins?

Réponses

  • MalaMala Membre, Modérateur
    20:50 modifié #2
    Lire un fichier texte ligne par ligne...

    As-tu vu cette discussion? Cela devrait faire ton bonheur je pense.
  • tabliertablier Membre
    20:50 modifié #3
    Oui, je viens de voir cela. Dans ma première recherche je ne l'avais pas trouvé car je n'avais pas donné les bons mots clefs!
    Bon, cet article résoud presque complètement mon problème, merci!  :P
  • elfelf Membre
    20:50 modifié #4
    Ensuite, une petite regex et pouf =)
  • AliGatorAliGator Membre, Modérateur
    20:50 modifié #5
    Pas tout à  fait, une regex n'est pas le plus adapté ici au vu des cas particuliers que sont les échappements de quotes par doublement entre autres.
    Donc ça marche si ton CSV n'a pas de quote, ou en a partout autour de chaque champ mais pas à  l'intérieur... mais pas pour les champs étalés sur plusieurs lignes ou ceux contenant des quotes.
  • elfelf Membre
    20:50 modifié #6
    En effet, Ali, tu as raison...

    Moi dans ma situation j'avais parsé des fichier remplis d'info de license dans le style de :

    "Prénom","Nom","email@domain.com"\r\n
    


    Donc pour moi c'était amplement suffisant, mais pas idéal
  • tabliertablier Membre
    20:50 modifié #7
    Je pense que j'ai un cas assez simple. Je n'ai pas encore essayé, mais je pensais récupérer les strings en utilisant:
    NSArry *lamatrice = [la_ligne componentsSeparatedByString:@"\t"] ;
    

    Quitte à  régler le problème des " ou ' séparement pour chaque string récupéré.
    ça vous paraà®t idiot?
  • AliGatorAliGator Membre, Modérateur
    20:50 modifié #8
    Non, pas spécialement, c'est même une façon plutôt pratique. A condition que tu sois sûr que ton CSV utilise la tabulation comme séparateur (historiquement, CSV = Comma Separated Value, donc séparateur = virgule ; puis c'est devenu de plus en plus courant d'utiliser des tabulations, et parfois on en voit utilisant des point-virgules. Mais dans tous les cas c'est évidemment le même séparateur qui est utilisé tout au long du fichier encore heureux)

    Sinon pour corriger les erreurs de découpage avec componentsSeparatedByString :
    Exemples de lignes chiantes :
    a,b,"cd"",""ef"
    Cette ligne correspond à  3 éléments
    a
    b
    cd","ef
    Pourtant quand tu fais ton [tt]componentsSeparatedByString:@,[/tt], tu obtiendras :
    a
    b
    "cd""
    ""ef"


    Une idée d'algo pour pas te compliquer la vie (peut-être pas le plus optimisé mais celui où on se prend sans doute moins la tête, à  part la solution du parcours caractère par caractère avec suivi d'un flag si on est dans une chaine "quotée" ou pas, mais bon) :

    Soit V = CheckDeb(C) le test défini comme suit sur une chaà®ne C et retournant un booléen V :
    - Supprimer tous les espaces en début et fin de C
    - Supprimer tous les double-guillemets (2 guillemets consécutifs) du résultat (pour pas perturber)
    - V est vrai si le résultat commence par un guillemet, faux sinon
    Et le test V = CheckFin(C) qui fait la même chose mais en testant si le résultat se termine par un guillemet (ou pas)
    --> Ce test permet de vérifier si une chaà®ne est le début d'un élément qui a été coupé par erreur, et de trouver l'élement de fin correspondant :

    1) Effectuer Comps[ L ] = [ligne componentsSeparatedByString:@\t] sur chaque ligne Lde ton fichier CSV.
    2) Ensuite pour chaque composant C, effectuer le test D = CheckDeb(C), puis regarder si D est vrai. Si oui, c'est une chaà®ne qui est le début d'un composant tronqué par erreur. Dans ce cas, enlever le guillemets du début du composant C, puis :
    2a) effectuer F=CheckFin(C2) sur le composant C2 qui suit
    2b) concaténer : C = C + C2.
    2c) Et recommencer 2a tant que F est faux (donc s'arrêter quand F est vrai, en en profitant pour supprimer le guillemet à  la fin)

    Sachant que le composant "qui suit" peut être le suivant dans le tableau Comps[ i ]... ou si on est arrivé à  la fin, le premier de Comps[ i+1 ] (= début de la ligne suivante) !

    Cet algo permet de réunifier les composants qui auraient été coupés en deux (ou plus) par erreur, mais ça fait bcp de replaceString (qui, j'imagine, en interne fait une boucle de parcours des caractères) et de appendString aussi, pour la partie 2 de l'algo. Donc à  se demander si ça vaut pas le coup de faire un parcours caractère par caractère dès le début :
    - avec un flag "inQuotedString" dont on inverse l'état quand on rencontre une quote, sauf si cette dernière est suivie d'une autre quote
    - le flag permettant ensuite de savoir si on doit considérer les séparateurs de ligne (\n) et de colonnes (\t) comme des vrais séparateurs ou comme à  considérer comme caractères (échappés)


    Voilà  pour les idées.
  • tabliertablier Membre
    20:50 modifié #9
    Oui je vois, ça devrait marcher.

    Pour le séparateur d'élément, comme je peux avoir des chiffres écrits en Français ( 34,5 par exemple) je prends la précaution de demander des fichiers "Texte-Tabulé" et non des fichiers CSV.
  • AliGatorAliGator Membre, Modérateur
    20:50 modifié #10
    Ok, de toute façon c'est souvent plus lisible dans le cas où on les ouvre dans un éditeur de texte pour vite fait voir leur contenu...
    Ceci dit juste histoire de pinailler...c'est à  ça aussi que servent les guillemets dans ces fichiers, à  encapsuler le contenu des colonnes pour que tout ce qui est entre les guillemets soit compris comme du texte brut :P
    Mais bon après autant utiliser les tabulations, je suis d'accord (d'ailleurs moi je préfère aussi les CSV utilisant les tabs, même si historiquement c'est la virgule)
    Article,Quantité,Prix
    Tomates,5,"8,60"
    "Carottes rapées",1,"4,20"
    Mac Pro,1,"2200,00"
  • elfelf Membre
    20:50 modifié #11
    Bah moi je préfère les CSV qui utilise la virgule... c'est plus lisible...
  • tabliertablier Membre
    20:50 modifié #12
    Pour la lecture ligne à  ligne d'un fichier csv, c'est expliqué plus haut.

    Comme j'ai enfin eu un peu de temps libre j'ai écris une méthode d'extraction des champs de la ligne.
    Mais, étant d'origine Normande (ptet' bin qu'oui, ptet' bin qu'non  ??? ) , je n'ai pas voulu choisir entre tabulation, virgule ou point virgule.

    Je mets dans le fichier joint (extraire.zip) la méthode qui, après essais, me semble très bien marcher.




Connectez-vous ou Inscrivez-vous pour répondre.