problèmes lecture d'un fichier texte

problèmes lecture d'un fichier texte - Ruby/Rails - Programmation

Marsh Posté le 24-12-2007 à 16:04:18    

Bonjour,
 
Débutant en ruby je n'ai pas trouvé de solution simple pour parcourir un fichier texte ayant cette structure :
 
user1
user2
user3
etc..
 
J'ai trouvé comment lire chaque ligne et écrire dans le fichier mais j'aimerais savoir comment pourrait-on :
 
-aller directement à la fin du fichier (sinon j'écrase le fichier à chaque fois que j'écris
-gérer une sorte de curseur pour écrire à la ligne 4 par exemple.  
 
Autre problème plus important dans mon cas :
 
J'envois à mon programme une chaine de caractère. Je parcours mon fichier à la recherche de cette chaine (un mot par ligne dans le fichier). J'utilise ce code:
 

Code :
  1. fic = File.open("users.txt", "r" )
  2.    ok=false
  3.    fic.each_line { |ligne|
  4.     puts "ligne lue: "+ligne
  5.     lignelu=ligne
  6.     if lignelu==logpass
  7.      puts "comparaison ok"
  8.       ok=true
  9.     end
  10.    }


Le parcours s'effecue correctement mais la comparaison ne marche jamais. Pourtant, avec des puts j'otbtient bien lignelu=logpass(chaine envoyée au programme).
 
je pensais à un problème d'encodage... ou y-a-t-il un autre moyen de comparer en ruby des chaines de caratères?
 
merci d'avance...  :)

Reply

Marsh Posté le 24-12-2007 à 16:04:18   

Reply

Marsh Posté le 24-12-2007 à 17:28:49    

peut etre passer par un fichier yaml ?

Reply

Marsh Posté le 28-12-2007 à 22:51:01    

skystef2 a écrit :

-aller directement à la fin du fichier (sinon j'écrase le fichier à chaque fois que j'écris


Il faut ouvrir en mode "a" (append), ou "a+" (append & read), comme indiqué dans la documentation de la classe IO

skystef2 a écrit :

-gérer une sorte de curseur pour écrire à la ligne 4 par exemple.


Tu peux utiliser IO#pos= ou IO#seek (qui sont équivalent, la différence étant que tu peux spécifier l'offset de #seek alors que celui de #pos= est fixé). Attention, les deux fonctionnent non pas par ligne mais par octet dans le fichier.

 

En toute honnêteté, à moins que tu ais de gros problèmes de performances je te conseillerais plutôt d'écrire dans un nouveau fichier de sortie (en recopiant tout ce que tu ne touches pas), et quand ton écriture est terminée de dégager le fichier d'entrée et de renommer celui de sortie, éditer efficacement un fichier sans tout pêter c'est pas super simple et rarement des plus utiles.

skystef2 a écrit :


Autre problème plus important dans mon cas :

 

J'envois à mon programme une chaine de caractère. Je parcours mon fichier à la recherche de cette chaine (un mot par ligne dans le fichier). J'utilise ce code:

 
Code :
  1. fic = File.open("users.txt", "r" )
  2.    ok=false
  3.    fic.each_line { |ligne|
  4.     puts "ligne lue: "+ligne
  5.     lignelu=ligne
  6.     if lignelu==logpass
  7.      puts "comparaison ok"
  8.       ok=true
  9.     end
  10.    }



1. Je vois pas l'intérêt de garder une référence sur ton fichier de cette manière, appeler directement each_line sur File#open
2. La méthode each_line ne supprime pas le séparateur de ligne, donc quand tu lis la 2e ligne (par exemple) tu récupères non pas "user2" mais "user2\n", que tu compares à "user2", et la comparaison est donc invalide. Utiliser String#chomp pour retirer le séparateur de fin de ligne avant de faire la comparaison.
3. C'est quoi l'intérêt de l'affectation "lignelu = logpass"?

 

Au final, en utilisant ta méthode j'écrirais ça de la manière suivante:

Code :
  1. found = false
  2. File.open("users.txt" ).each_line do |line|
  3.  found = true if line.chomp == logpass
  4. end


mais si j'ai bien compris ce que tu veux faire (tester si tu as le contenu de "logpass" sur une des lignes de ton fichier), personnellement j'aurais tendance à écrire un truc du style:

 
Code :
  1. found =  File.open("users.txt" ).readlines.select {|line| line.chomp == logpass}.length > 0


  • On lit tout le fichier et on colle ses lignes dans un array (via IO#readlines)
  • On ne garde que les lignes contenant logpass (via Enumerable#select, qui sert de filtre)
  • On regarde si le résultat est différent de 0 (si c'est 0 aucune ligne n'a été trouvée)


Message édité par masklinn le 28-12-2007 à 22:52:20

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed