Stockage de lignes d'un fichier dans un tableau

Stockage de lignes d'un fichier dans un tableau - C++ - Programmation

Marsh Posté le 08-11-2002 à 10:57:24    

Bonjour,
 
je suis de retour :hello
 
J'ai 1 pb à vous soumettre :
 
comment écrire en c ou c++ le programme suivant :
stocker dans un tableau dynamique toutes les lignes d'un fichier texte, sachant que le nb de lignes du fichier est inconnu (car variable) et le nombre de caractères pour chaque ligne est inconnu (car variable)
en gros, ce sera un tableau de chaines de caractères (nb de caractères variable) de dimension variable  
 
ça sent l'alloc dynamique mais je cale... :(
 
A+ Sonia

Reply

Marsh Posté le 08-11-2002 à 10:57:24   

Reply

Marsh Posté le 08-11-2002 à 15:51:08    

help  :sweat:

Reply

Marsh Posté le 08-11-2002 à 22:23:18    

Une méthode brutale consiste à lire tout le fichier dans une chaine allouée à la taille du fichier. Si on veut alors gérer les lignes, on cherche les CrLf.
 
Up, Up !

Reply

Marsh Posté le 08-11-2002 à 22:29:26    

en C ou en C++?


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 09-11-2002 à 11:12:34    

DOS, Windows, Nunux ?
 
Up !

Reply

Marsh Posté le 12-11-2002 à 14:06:20    

sous Windows
 
Avez-vous un algo à me proposer ? Je cale à cause de l'alloc dynamique  :(  
 
J'ai pensé à ceci :  :??:  
Ouvrir le fichier en mode texte
Compter le nombre de lignes (nblignes) en détectant le nombre de retour-chariot.
Construire un tableau de chaînes de caractères en réservant nblignes chaînes de caractères.
Pour chaque ligne du fichier:
Lire le fichier à nouveau en utilisant une fonction récupérant une ligne (détection du retour-chariot) du style getline
Stocker la ligne dans le tableau
Indice suivant pour le tableau
FinPour
Les hics : comment réserver la place pour le tableau ? (syntaxe)Comment utiliser getline sans avoir à fournir une taille maximale de la ligne à stocker ?  :heink:  
 
Merci d'avance. Sonia

Reply

Marsh Posté le 12-11-2002 à 14:14:50    

je te propose une réponse en algo car je suis nul en C
 
 
tu stockes tout ton fichier en mémoire.
 
Tu parcours ton fichier. A chaque fois que tu rencontres une séquence de fin de ligne, tu as à l'adresse suivante le début d'une ligne -> tu affecte cette adresse à ton pointeur de rang n, puis tu incrémente n.
Comme celà tu n'as pas à gérer la taille des lignes. (la longueur est obtenue par différence entre les adresses fournies par les pointeurs n et n+1 (-1 ou -2 selon si c'est un texte unix ou Windows))
 
A+

Reply

Marsh Posté le 12-11-2002 à 17:01:33    

Pop  :bounce:  
 
Sonia

Reply

Marsh Posté le 12-11-2002 à 17:42:44    

Si tu veux un algo très général et qui marche aussi bien pour les fichiers de 500 Ko sans un seul retour chariot, ou les fichiers de même taille avec 50 000 lignes, je te propose la structure suivante.
 
Dans l'idée, il vaut mieux ne lire le fichier qu'une seule fois. Les entrées/sorties sont ce qu'il y a de plus long à exécuter (même si souvent l'OS masque ça par un joli petit cache disque).
Ensuite, on ne sait pas combien d'octets on va lire, donc il faut, pour chaque ligne, une structure qui grossisse en fonction des besoins. Enfin, on ne sait pas combien de lignes on va lire : même raisonnement, il faut une structure à grosseur dynamique.
 
La structure la plus dynamique qui existe, et la plus économe en consommation mémoire, c'est la liste chaînée. Donc, dans l'idée, tu peux définir une liste chaînée où chaque noeud est une ligne, et, pour chaque ligne, une autre liste chaînée pour son contenu.
 
Maintenant, on ne va pas définir un noeud de liste chaînée par caractère, la consommation mémoire exploserait aussi !
 
Alors je te propose que chaque noeud soit une sorte de buffer : on aurait des morceaux de ligne (de, par exemple, 4000 caractères), et des paquets de lignes (par exemple, 100 lignes).
 
Maintenant, l'implémentation (C++). Je suppose que tu as une classe template ChainedList qui implémente proprement les listes chainées.
 
Tu pourrais alors écrire :

Code :
  1. const int TAILLE_MORCEAU = 4096;
  2. const int TAILLE_PAQUET  =  100;
  3. class MorceauLigne {
  4.   char  buffer[TAILLE_MORCEAU];
  5.   long  taille;   // Taille réellement utilisée
  6.   ...
  7. }
  8. class Ligne {
  9.   ChainedList<MorceauLigne>  ligne;
  10.   long                       longueur;
  11.   ...
  12. }
  13. class PaquetLigne {
  14.   Ligne  paquet[TAILLE_PAQUET];
  15.   long   taille;   // Nombre de lignes réellement utilisées
  16.                    // dans ce paquet
  17.   ...
  18. }
  19. class Texte {
  20.   ChainedList<PaquetLigne>  texte;
  21.   long                      numLignes;
  22.   ...
  23. }


 
Voilà, c'est pour l'idée. Maintenant, côté implémentation C++ pure et dure, il y a clairement des petites améliorations à apporter pour l'efficacité (par exemple, l'utilisation de pointeurs sur Ligne plutôt que des objets dans le tableau défini dans PaquetLigne).


Message édité par BifaceMcLeOD le 12-11-2002 à 18:17:52
Reply

Marsh Posté le 12-11-2002 à 18:14:07    

les #define tu oublies seuplé


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 12-11-2002 à 18:14:07   

Reply

Marsh Posté le 12-11-2002 à 18:15:56    

J'aime programmer crade. :D
 
Bon, OK, j'édite mon post. :sarcastic:

Reply

Marsh Posté le 12-11-2002 à 19:09:06    

voire unsigned  :na:


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 12-11-2002 à 19:46:07    

pourquoi pas ça en C++ ?
si ça peut t'aider.
 

Code :
  1. // Voilà les includes
  2. #include <iostream>
  3. #include <string>
  4. #include <list>
  5. using namespace std;
  6. // Là c la fonction qui stoque ttes les lignes ds une list chainée
  7. string tmp;
  8. list<string> pStrL;
  9. list<string>::iterator iStrL;
  10. ifstream Fichier(NomFichier);
  11. while(!Fichier.eof())
  12. {
  13. getline(Fichier,tmp);
  14. pStrL.push_back(tmp);
  15. }
  16. Fichier.close();

Reply

Marsh Posté le 12-11-2002 à 21:07:43    

Larry99 a écrit a écrit :

pourquoi pas ça en C++ ?
si ça peut t'aider.
 

Code :
  1. // Voilà les includes
  2. #include <iostream>
  3. #include <string>
  4. #include <list>
  5. using namespace std;
  6. // Là c la fonction qui stoque ttes les lignes ds une list chainée
  7. string tmp;
  8. list<string> pStrL;
  9. list<string>::iterator iStrL;
  10. ifstream Fichier(NomFichier);
  11. while(!Fichier.eof())
  12. {
  13. getline(Fichier,tmp);
  14. pStrL.push_back(tmp);
  15. }
  16. Fichier.close();






 
 
j'ai déjà repondu
http://forum.hardware.fr/forum2.ph [...] subcat=386
 
 

Code :
  1. while(!Fichier.eof())
  2. {
  3. getline(Fichier,tmp);
  4. pStrL.push_back(tmp);
  5. }


 
si l'erreur rencontré n'est pas une fin de fichier?
 
préfère toujours
 
while(getline(stream, tmp)) ou while(cin >> tmp)


---------------
du bon usage de rand [C] / [C++]
Reply

Marsh Posté le 13-11-2002 à 17:42:53    

Bonjour,
 
merci bcp :)
c ce ki me fallait !!!
Allé, a+
 
Sonia  :hello:

Reply

Marsh Posté le 13-11-2002 à 20:04:44    

Taz@PPC a écrit a écrit :

 
si l'erreur rencontré n'est pas une fin de fichier?
préfère toujours
while(getline(stream, tmp)) ou while(cin >> tmp)




 
Moi j'utilie "stream.fail()" avec succes

Reply

Sujets relatifs:

Leave a Replay

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