[C++] Erreur lors de lecture/écriture d'un certain nb de fichiers

Erreur lors de lecture/écriture d'un certain nb de fichiers [C++] - C++ - Programmation

Marsh Posté le 22-02-2005 à 14:26:10    

Bonjour,
 
J'ai créé une classe StringList qui me permet de stocker dans un vecteur de string, des chaines de caractères.
 
Voici ma fonction de lecture :

Code :
  1. void StringList::LoadFromFile(string nom_fichier)
  2. {
  3.         this->Clear();
  4.         char str[10000];
  5.         ifstream fichier(nom_fichier.c_str());
  6.         if(fichier)
  7.         {
  8.              while(fichier.getline(str,10000))
  9.                 this->Add(StrReplace(ToString(str), "\r", "" ));
  10.              fichier.close();
  11.         }
  12. }


 
Et voici ma fonction d'écriture :  

Code :
  1. void StringList::SaveToFile(string nom_fichier)
  2. {
  3. ofstream fe (nom_fichier.c_str(), ios::trunc);
  4. int i;
  5. if(fe)
  6. {
  7.         i=0;
  8.         while(i<this->Count)
  9.         {
  10.                 fe << this->Strings[i].c_str() << "\r\n";
  11.                 i++;
  12.         }
  13.         fe.close();
  14. }
  15. else
  16.      cout << "Erreur d'ouverture en ecriture du fichier " << nom_fichier << endl;
  17. }


 
Au bout d'un certain nombre de lectures/écritures (nombre aléatoire !!), mon programme plante et ne parvient plus à ouvrir de fichiers en écriture.
 
Je ne comprends pas du tout pourquoi !  :sweat: Auriez-vous des pistes pour m'éclairer ?? Merci !


Message édité par benj63 le 22-02-2005 à 14:26:28
Reply

Marsh Posté le 22-02-2005 à 14:26:10   

Reply

Marsh Posté le 22-02-2005 à 14:28:30    

Petite précision : je suis sous RedHat 9 et mon compilateur est GCC 3.2.2-5

Reply

Marsh Posté le 22-02-2005 à 14:30:06    

hile(fichier.getline(str,10000))
 
 
c'est pas fini ces conneries ?
 
 
std::string line;
 
while(std::getline(fin, line)) { ... }

Reply

Marsh Posté le 22-02-2005 à 14:32:22    

c'est ce que j'avais mis avant... mais ça ne fonctionnait pas mieux...  :sweat:

Reply

Marsh Posté le 22-02-2005 à 14:36:33    

Voici ma fonction de lecture, corrigée :
 

Code :
  1. void StringList::LoadFromFile(string nom_fichier)
  2. {
  3.         this->Clear();
  4.         string str;
  5.         ifstream fichier(nom_fichier.c_str());
  6.         if(fichier)
  7.         {
  8.              while(getline(fichier,str))
  9.                 this->Add(StrReplace(str, "\r", "" ));
  10.              fichier.close();
  11.         }
  12. }

Reply

Marsh Posté le 22-02-2005 à 14:36:53    

déjà passe en TOUT std::string, ensuite on verra

Reply

Marsh Posté le 22-02-2005 à 14:37:28    

c'est quoi ta fonction StrReplace ?

Reply

Marsh Posté le 22-02-2005 à 14:47:36    

J'ai tout passé en std::string... même erreur.
 
Ma fonction StrReplace permet de remplacer dans une chaine de caractères, un bout de chaine par une autre :

Code :
  1. string StrReplace(std::string chaine, std::string avant, std::string apres)
  2. {
  3. int pos;
  4. pos=StrPos(avant, chaine);
  5. while(pos!=-1)
  6. {
  7.         chaine.replace(pos-1, avant.length(), apres);
  8.         pos=StrPos(avant, chaine);
  9. }
  10. return chaine;
  11. }


 
avec StrPos pour trouver la position d'un caractère dans une chaîne :

Code :
  1. int StrPos(std::string caractere, std::string chaine)
  2. {
  3.         int pos;
  4.         pos=chaine.find(caractere);
  5.         if(pos!=-1)
  6.                 pos=pos+1;
  7.         return pos;
  8. }

Reply

Marsh Posté le 22-02-2005 à 15:03:26    

bon et alors ça plante ou ?

Reply

Marsh Posté le 22-02-2005 à 15:17:16    

En fait j'ouvre une dizaine de fichiers, et j'en écris au total plus d'un milliers. C'est généralement aux alentours de 1000 fichiers écrits qu'il "plante" dans le sens où il ne parvient plus à ouvrir les fichiers en écriture dans SaveToFile :
 

Code :
  1. ofstream fe (nom_fichier.c_str(), ios::trunc);


 
renvoie NULL (alors que le fichier n'existe pas encore, et qu'il n'y aucune limitation d'accès à ce répertoire...)

Reply

Marsh Posté le 22-02-2005 à 15:17:16   

Reply

Marsh Posté le 22-02-2005 à 15:18:38    

comment ça renvoie NULL ?

Reply

Marsh Posté le 22-02-2005 à 15:22:28    

Ma fonction SaveToFile renvoie :
 
Erreur d'ouverture en ecriture du fichier nom_fichier1098.txt
Erreur d'ouverture en ecriture du fichier nom_fichier1099.txt
Erreur d'ouverture en ecriture du fichier nom_fichier1100.txt
Erreur d'ouverture en ecriture du fichier nom_fichier1101.txt
Erreur d'ouverture en ecriture du fichier nom_fichier1102.txt
Erreur d'ouverture en ecriture du fichier nom_fichier1103.txt
Erreur d'ouverture en ecriture du fichier nom_fichier1104.txt
...
 
donc je me dis que fe est NULL non ?

Reply

Marsh Posté le 22-02-2005 à 15:23:18    

c'est un pointeur fe ? d'où il sort ce message d'erreur ?

Reply

Marsh Posté le 22-02-2005 à 15:29:40    

Dans SaveToFile :
 

Code :
  1. ofstream fe (nom_fichier.c_str(), ios::trunc);
  2. if(!fe)
  3.    cout << "Erreur d'ouverture en ecriture du fichier " << nom_fichier << endl;


 
mais ce n'est peut-être pas ainsi qu'on vérifie si un fichier est bien ouvert ?!

Reply

Marsh Posté le 22-02-2005 à 15:32:49    

ulimit -n ?
 
ce que je comprends pas c'est pourquoi les descripteurs ne sont pas fermés ... tu ferais pas de la rétention de stream quelque part ?

Reply

Marsh Posté le 22-02-2005 à 15:37:39    

[quote=989912,0,15,72553]ulimit -n ?
 
ce que je comprends pas c'est pourquoi les descripteurs ne sont pas fermés ... tu ferais pas de la rétention de stream quelque part ?[/quote]
 
ulimit -n me retourne 1024... donc 1024 fichiers avant bug ou je mélange tout ?!
 
Il est possible que je fasse de la rétention de stream, comment m'en assurer ??
 
Merci  :jap:

Reply

Marsh Posté le 22-02-2005 à 15:41:29    

genre tu maintiendrais pas une collection de stream ? ou tu ferais pas des new ofstream() ?

Reply

Marsh Posté le 22-02-2005 à 15:42:16    

ah peut-être... enfin pas de new() ostream mais maintenir une collection?... Que veux-tu dire par là ?

Reply

Marsh Posté le 22-02-2005 à 15:45:58    

ben une liste un vecteur :o

Reply

Marsh Posté le 22-02-2005 à 15:51:05    

non je ne fais pas de liste de vecteurs de fstream, ifstream ou ofstream... Par contre y'a-t'il une commande comme ulimit -n pour vérifier lors de l'exécution de mon programme s'il empile des streams sans les libérer au fûr et à mesure ?

Reply

Marsh Posté le 22-02-2005 à 15:53:26    

essaie de strace'r ton programme (man strace)

Reply

Marsh Posté le 22-02-2005 à 15:55:31    

Est-que tu as une fonction récursive quelque part ?


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 22-02-2005 à 15:57:04    

[quote=989973,0,22,21301]Est-que tu as une fonction récursive quelque part ?[/quote]
 
Oui, StrReplace (voir ci-dessus)

Reply

Marsh Posté le 22-02-2005 à 16:08:30    

Code :
  1. #include <iostream>
  2. #include <sstream>
  3. #include <fstream>
  4. #include <string>
  5. #include <stdexcept>
  6. #include <cstring>
  7. #include <cstdlib>
  8. namespace My
  9. {
  10.   using std::string;
  11.   string get_first_line(const string &filename)
  12.   {
  13.     std::ifstream f(filename.c_str());
  14.     string line;
  15.     if(!f) {
  16.       std::ostringstream os;
  17.       os << "Cannot open "
  18.  << '\'' << filename.c_str() << '\''
  19.  << '\t'
  20.  << std::strerror(errno);
  21.       throw std::runtime_error(os.str());
  22.     }
  23.     std::getline(f, line);
  24.     return line;
  25.   }
  26. }
  27. int main()
  28. {
  29.   std::string filename;
  30.   unsigned i = 0;
  31.   while(std::getline(std::cin, filename))
  32.     {
  33.       i++;
  34.       try
  35. {
  36.   My::get_first_line(filename);
  37. }
  38.       catch(std::exception &ex)
  39. {
  40.   std::cerr << ex.what() << std::endl;
  41.   // break;
  42. }
  43.       if(i % 1000 == 0)
  44. std::cout << i << '\n';
  45.     }
  46.   std::cout << "Opened files : " << i << '\n';
  47. }


 
ça donne quoi ce genre de chose chez toi ?
 
find /etc -type f 2>/dev/null | ./a.out
 
par exemple

Reply

Marsh Posté le 22-02-2005 à 16:12:06    

Il faut faire des close() avant d'entrer en récursion...


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 22-02-2005 à 16:12:43    

[quote=990029,0,25,21301]Il faut faire des close() avant d'entrer en récursion...[/quote]rien à voir, merci de lire le code.

Reply

Marsh Posté le 22-02-2005 à 16:12:57    

:heink: Est-ce que cette fonction ne poserait pas problème par hasard ?
(en ne fermant pas le opendir)  
 

Code :
  1. bool DirectoryExists(string repertoire)
  2. {
  3. return(opendir(repertoire.c_str()));
  4. }

Reply

Marsh Posté le 22-02-2005 à 16:13:57    

man opendir
man 2 stat <- remplace par ça

Reply

Marsh Posté le 22-02-2005 à 16:14:15    

et les const &, c'est quand tu veux

Reply

Marsh Posté le 22-02-2005 à 16:14:23    

[quote=990031,0,26,72553]rien à voir, merci de lire le code.[/quote]
J'te parle pas à toi.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 22-02-2005 à 16:15:10    

il n'empêche


Message édité par Taz le 22-02-2005 à 16:15:17
Reply

Marsh Posté le 22-02-2005 à 16:19:55    

rapidement
 

Code :
  1. bool isDirectory(const std::string &filename)
  2. struct stat buf;
  3. if(stat(filename.c_str(), &buf) == -1) return false;
  4. return S_ISDIR(buf.st_mode);
  5. }


Message édité par Taz le 22-02-2005 à 16:20:13
Reply

Marsh Posté le 22-02-2005 à 16:21:09    

[quote=990019,0,24,72553]
 
(...)
 
ça donne quoi ce genre de chose chez toi ?
 
find /etc -type f 2>/dev/null | ./a.out
 
par exemple[/quote]
 
me donne :  
 
1000
Opened files : 1264

Reply

Marsh Posté le 22-02-2005 à 16:22:05    

ouais, je pense vraiment que c'est ta fuite de ressources au niveau d'opendir. Tu as peut être d'autres fuites, mais en corrigeant ça tu devrais déjà aller plus loin

Reply

Marsh Posté le 22-02-2005 à 16:24:53    

Faut-il inclure une unité pour utiliser stat comme tu le fais dans ton code de isDirectory ?

Reply

Marsh Posté le 22-02-2005 à 16:26:03    

STAT(2)                   Manuel du programmeur Linux                  STAT(2)
 
NOM
       stat, fstat, lstat - Obtenir le statut d’un fichier (file status).
 
SYNOPSIS
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>
 
 
 
c'était trop te demander d'ouvrir le manuel de stat ?

Reply

Marsh Posté le 22-02-2005 à 16:31:29    

Désolé, je n'ai pas encore pris l'habitude de faire des man lorsque je programme sous Unix... Je développe la plupart de mes applications sous C++ Builder sous Windows, et là depuis peu en me plongeant dans du codage + standard et + propre sous Unix, j'ai un peu du mal pour chercher de l'aide etc...  :sweat:  
 
Enfin bref, il est vrai que j'aurais pu trouver cette réponse tout seul.
 
 :jap:  :jap: Merci pour ton aide, c'était effectivement la fonction DirectoryExists() qui ouvrait des tas de stream sans les fermer...

Reply

Marsh Posté le 22-02-2005 à 16:33:04    

perdu. ta fonction DirectoryExists ouvre des descripteurs de fichiers avec la fonction C POSIX opendir, et ne les referme pas.

Reply

Marsh Posté le 22-02-2005 à 16:39:38    

oui enfin je m'étais compris à mon niveau...
 
merci pour ta correction.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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