Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1528 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  fstream / Modifier une valeur spécifique dans un fichier C++

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

fstream / Modifier une valeur spécifique dans un fichier C++

n°2157148
G_Nathan
Posté le 18-09-2012 à 18:29:02  profilanswer
 

Bonjour,
 
Une questino sur un problème sans doute très simple, mais sur lequel je n'ai pas trouvé d'aide précise et claire.
Je voudrais ecrire un fichier avant d'en changer plus tard certaines valeurs spécifiques répondant à des critères donnés.
 
Plus simplement, dans une version basique de ce problème, j'ai le code :
 

Code :
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4. using namespace std;
  5. int main()
  6. {
  7. int i,j,k,n;
  8. n = 10;
  9. string filename;
  10. filename = "file.txt";
  11. cout << filename << endl;
  12. // Write
  13. ofstream ofs;
  14. ofs.open(filename.c_str());
  15. for(i=-n;i<n;i++)
  16. {
  17.  for(j=-n;j<n;j++)
  18.   ofs << i*j << " ";
  19.  ofs << endl;
  20. }
  21. ofs.close();
  22. // Read and change
  23. fstream fs;
  24. fs.open(filename.c_str(), ios::in | ios::out );
  25. for(i=-n;i<n;i++)
  26. {
  27.  for(j=-n;j<n;j++)
  28.  {
  29.   fs >> k;
  30.   if (k<0)
  31.   {
  32.    fs << -k;
  33.   }
  34.  }
  35. }
  36. }


 
J'écris ainsi un fichier simple au début (avec des valeurs positives ou négatives), avant d'en relire le contenu.
Je voudrais ainsi, à titre d'exemple, en changer les valeurs positives en négatives, mais il semble que cela ne soit fonctionne pas.
 
Le fichier demeure inchangé, bien que le test soit vérifié régulièrement. Qu'est ce que j'ai raté ? Est-ce que je dosi changer quelquechose dans ces dernières lignes ?
Je pensais que l'utilisation d'un ' fstream ' résoudrais le problème mais ce n'est apparemment pas le cas.
 
D'avance merci de votre aide,
 
Nathan

mood
Publicité
Posté le 18-09-2012 à 18:29:02  profilanswer
 

n°2157174
Farian
Posté le 18-09-2012 à 23:38:04  profilanswer
 

Bonjour !
 
Tout d'abord, votre programme ne teste pas que les actions ont été correctement effectuées !
 
 -> la méthode "open" ne renvoie rien, il faut tester que l'ouverture s'est bien passée avec la méthode "isopen"
 
 -> Après chaque opération ">>" et "<<" il peut être intéressant de tester le retour à l'aide de la méthode "fail" (qui renvoie "true" si une erreur s'est produite durant la lecture/écriture).
 
En instrumentant votre programme, vous vous rendrez compte, durant la deuxième phase, que les lectures se passent correctement puis que la première écriture se passe mal. Ensuite, toutes les opérations échouent (les pointeurs de lecture / écriture sont positionnés à -1, plus aucune opération n'est réellement effectuée).
 
Pourquoi ce fonctionnement ?
 
Je ne saurais vous le dire exactement ... Mais, de toutes façons, modifier des valeurs dans un fichier "texte", avec donc des valeurs qui n'ont pas la même taille, ne peut fonctionner correctement (remplacer dans le texte "-10" par "10" donnerait "100" à la relecture).
 
Par ailleurs, quand vous lisez (<< ) dans le fichier, le pointeur de lecture et d'écriture sont décalés (ce qui signifie que vous écririez dans le fichier juste après ce que vous venez de lire, au lieu de remplacer ...).
 
Si vous voulez faire ce genre de modifications :
 
 * Lisez et écrivez des valeurs en binaire, qui ont tous la même taille,
 * Avant de réécrire, décalez le pointeur d'écriture pour réécrire à l'endroit de votre lecture, pas à la suite ...
 
Sinon, une version qui fonctionne presque (les fonctionnement n'est pas exactement le même en début de ligne, en milieu de ligne et en fin de ligne) serait la suivante  (mais la façon de faire est "très moche" :) ):  
 

Code :
  1. #include <iostream>
  2.     #include <fstream>
  3.     #include <string>
  4.     using namespace std;
  5.     int main()
  6.     {
  7.     int i,j,k,n;
  8.     n = 10;
  9.     string filename;
  10.     filename = "file.txt";
  11.     cout << filename << endl;
  12.     // Write
  13.     ofstream ofs;
  14.     ofs.open(filename.c_str());
  15.     for(i=-n;i<n;i++)
  16.     {
  17.      for(j=-n;j<n;j++)
  18.       ofs << i*j << " ";
  19.      ofs << endl;
  20.     }
  21.     ofs.close();
  22.     // Read and change
  23.     fstream fs;
  24.     fs.open(filename.c_str(), ios::in | ios::out );
  25.     long pos = 0;
  26.     for(i=-n;i<n;i++)
  27.     {
  28.      for(j=-n;j<n;j++)
  29.      {
  30.       fs >> k;
  31.       if (k<0)
  32.       {
  33.        fs.seekg(pos+1);
  34.        fs << -k << " " ; // <-- On rajoute un espace pour que le nombre positif prenne autant de place que le nombre négatif pour ne pas tout décaler ...
  35.       }
  36.       pos = fs.tellg();
  37.      }
  38.     }
  39.     }


 
J'espère avoir été clair et vous avoir aidé !
 
Bon courage !


Message édité par Farian le 18-09-2012 à 23:41:40
n°2157239
G_Nathan
Posté le 19-09-2012 à 14:10:46  profilanswer
 

Bonjour,

 

Merci de votre aide.
Je me suis tourne finalement vers un fichier Binaire pour gérer plus simplement ces opérations. La lecture et l'écriture sont correcte mais je ne parviens pas à modifier comme je le souhaite un élément. J'ai l'écriture :

 
Code :
  1. fstream fs;
  2. fs.open(filename.c_str(), ios::in | ios::out | ios::binary );
  3. unsigned long pos;
  4. for(i=-n;i<n;i++)
  5. {
  6.  for(j=-n;j<n;j++)
  7.  {
  8.   pos = fs.tellp();
  9.   fs.read(reinterpret_cast<char*> (&k), sizeof(int));
  10.   if (k<0)
  11.   {
  12.    cout << "Change val = " << k << " in " << -k << " / " << i << " " << j << endl;
  13.    fs.seekg(pos);
  14.    k = -k;
  15.    fs.write(reinterpret_cast<char*> (&k), sizeof(int));
  16.   }
  17.  }
  18. }
 

Mais elle ne semble pas correcte car seule la première valeur est modifiée et pas les suivantes que je trouve.

 

Quel pourrait être le problème ?
Ai je fait une erreur dans le choix des opérateurs binaires ?

 

D'avance merci de votre réponse,

 

G_Nathan


Message édité par G_Nathan le 19-09-2012 à 14:12:09
n°2157265
G_Nathan
Posté le 19-09-2012 à 17:17:17  profilanswer
 

Bonjour,

 

En pratique, j'avais oublié de mettre une commande '  fs.flush (); ' pour forcer l'écriture immédaite de la valeur. L'écriture corrigée :

 
Code :
  1. // Change
  2. fstream fs;
  3. fs.open(filename.c_str(), ios::in | ios::out | ios::binary );
  4. ifstream::pos_type pos;
  5. for(i=-n;i<n;i++)
  6. {
  7.  for(j=-n;j<n;j++)
  8.  {
  9.   pos = fs.tellg();
  10.   fs.read(reinterpret_cast<char*> (&k), sizeof(int));
  11.   if (k<0)
  12.   {
  13.    cout << "Change val = " << k << " in " << -k << " / " << i << " " << j << endl;
  14.    fs.seekp(pos);
  15.    k = -k;
  16.    fs.write(reinterpret_cast<char*> (&k), sizeof(int));
  17.    fs.flush ();
  18.   }
  19.  }
  20. }
 

semble fonctionner.

 

Y a -t-il quelque chose de choquant dans cette écriture ou voyez vous une manière plus simple de procéder en binaire ?

 

D'avance merci de vos conseils,

 

G_Nathan


Message édité par G_Nathan le 19-09-2012 à 17:17:28
n°2157287
gilou
Modérateur
Modzilla
Posté le 19-09-2012 à 19:32:38  profilanswer
 

Ce me semble bon.
Éventuellement, tu peux rajouter un const au cast du write: fs.write(reinterpret_cast<const char*> (&k), sizeof(int));
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2157476
I_m_back
Posté le 20-09-2012 à 19:18:08  profilanswer
 

Ne vaut il pas mieux écrire un fichier en // de celui qu'on lit ?


---------------
Ta peau de nacre noir, la courbe de ton cul
n°2157525
gilou
Modérateur
Modzilla
Posté le 21-09-2012 à 00:29:23  profilanswer
 

Pourquoi? pour aller plus vite?
Ça dépend de ses données. S'il a beaucoup d'inversions, oui. S'il en a peu, non.
A+,

Message cité 1 fois
Message édité par gilou le 21-09-2012 à 00:30:23

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2157546
I_m_back
Posté le 21-09-2012 à 09:13:01  profilanswer
 

gilou a écrit :

Pourquoi? pour aller plus vite?
Ça dépend de ses données. S'il a beaucoup d'inversions, oui. S'il en a peu, non.
A+,


 
Je ne sais pas, en fait je n'ai jamais rencontré ce cas (lire et écrire dans un fichier avec le même stream), et ça ne me serait pas venu à l'idée, du coup je me demandais s'il y avait une raison :D


---------------
Ta peau de nacre noir, la courbe de ton cul

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  fstream / Modifier une valeur spécifique dans un fichier C++

 

Sujets relatifs
Le if sur une valeur Null me retourne une erreur[Microsoft][C] convertir un char* en PCWSTR
Erreur de Link (Visual C++ 2005)[C#] Expression régulières
Visual C++ 2010 - Lancer un batch dos depuis un bouton(Cplex & C++) Comment résupérer les variables de base ?
commande SET + fichier .txtCommunication TCP Matlab-C++
[C / C++] Lire informations disque durAutomatisation -> récupération du fichier sur https
Plus de sujets relatifs à : fstream / Modifier une valeur spécifique dans un fichier C++


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR