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

  FORUM HardWare.fr
  Programmation
  C++

  Problème sur un flux de lecture à partir d'un fichier .txt

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème sur un flux de lecture à partir d'un fichier .txt

n°1421367
iamora
Posté le 07-08-2006 à 11:46:22  profilanswer
 

Bonjour,
 
Je rencontre une grande difficulté pour créer une fonction qui puisse lire à partir d'un fichier ".txt" une matrice trinagulaire supérieure et la stocker dans une variable matrice que j'ai définie préalablement.
 
N'étant pas expert en c++, j'ai codé en faisant abstraction de la gestion dynamique de la mémoire ce qui me joue des tours maintenant.
 
J'ai établi un code qui marche dans certains cas et qui est le suivant :
 
 

Code :
  1. #include "essai.h"
  2. #include <iostream>
  3. #include <fstream>
  4. #include <iomanip>
  5. using namespace std;
  6. using namespace std;
  7. int main()
  8. {
  9.   // Ouverture du fichier
  10.   ifstream fichierEntree("c:\\test1.txt", ios::in);
  11.   // Test d'ouverture du fichier
  12.     if (!fichierEntree) {
  13.         cerr << "Problème d'ouverture de fichier" << endl;
  14.         exit(1);
  15.     }
  16.     char* ligne;
  17.     int i = 0;
  18.     char * err = NULL;
  19. //double z;  
  20.     ligne = new char[10];
  21.     fichierEntree.getline(ligne, 4);
  22.     int conv1 = strtoul(ligne,0,10);
  23. ArrayLengthSpecifier dimension(conv1);
  24. cout << conv1 << endl;
  25. SymmetricMatrix covariance(dimension);
  26.     int longueur;
  27.     do
  28.   {
  29.   i = i + 1;
  30.   longueur = 9 * i + 1;
  31.   ligne = new char [longueur];//format "0.00E+00"
  32.   //donc 8 caractères; 9i=8i+ (i-1) espaces + élt nul terminal
  33.   fichierEntree.getline(ligne,longueur);
  34.   cout << ligne << endl;
  35.   
  36.   for (int j=1;j<=i;j++)
  37.  {
  38.   char temp[9];
  39.   for (int k=0;k<=7;k++)
  40.   {
  41.    temp[8]=0;
  42.    if (j==1)
  43.    temp[k] = ligne[k];
  44.    else
  45.    temp[k] = ligne[9* (j - 1) + k ];//attention dimension de 0 à n-1
  46.   }
  47.   const char* caractere=temp;
  48.   cout << caractere << endl;
  49.   covariance(i,j) = 2 * strtod(caractere, &err);
  50.   cout << covariance(i,j) << endl;
  51.   cout << covariance(j,i) << endl;
  52.  }
  53.  delete[] ligne;
  54.   }
  55.   while (!fichierEntree.eof());
  56.     fichierEntree.close();
  57. }


Ce code marche bien sur des matrices de types suivant :
 
 

Code :
  1. 3
  2. 1.23E-02
  3. 1.24E-02 1.26E-02
  4. 1.27E-02 1.23E-04 1.23E-03
  5. Par contre dès qu'il s'agit d'une matrice qui contient un nombre négatif (par exemple) :


 

Code :
  1. 3
  2. 1.23E-02
  3. -1.24E-02 1.26E-02
  4. 1.27E-02 1.23E-04 1.23E-03


 
Ma définition qui fixe la dimension de temp à 9, devient fausse puisque celle-ci avec le signe moins deviens égale à 10.
 
Aurriez vous une idée qui puisse contourner le problème??.  
 
J'ai pensé à imbriquer une instruction if à l'intérieure de ma boucle qui test si le premier caractère est "-" et à ce moment fait une réallocation de temp pour porter sa dimension à 10. Mais je ne sais pas comment coder ça en c++. Auriez vous une idée à me proposer, je suis vraiment bloquer la dessus ??
 
Merci de votre aide

mood
Publicité
Posté le 07-08-2006 à 11:46:22  profilanswer
 

n°1421442
franceso
Posté le 07-08-2006 à 13:34:29  profilanswer
 

Salut,
 
tu es en train de réinventer la roue en faisant à la main tes lectures de nombres. Il serait beaucoup plus simple d'utiliser les outils que te propose le C++.
 
Pour lire des nombres dans ton fichier d'entrée, il te suffit d'utiliser l'opérateur >> (exactement de la même manière que lorsque tu utilises l'opérateur << pour écrire sur un flux de sortie).
Exemple:

Code :
  1. ifstream fichierEntree( /*...*/ );
  2. double d;
  3. fichierEntree >> d;



---------------
TriScale innov
n°1421451
iamora
Posté le 07-08-2006 à 13:55:59  profilanswer
 

franceso a écrit :

Salut,
 
tu es en train de réinventer la roue en faisant à la main tes lectures de nombres. Il serait beaucoup plus simple d'utiliser les outils que te propose le C++.
 
Pour lire des nombres dans ton fichier d'entrée, il te suffit d'utiliser l'opérateur >> (exactement de la même manière que lorsque tu utilises l'opérateur << pour écrire sur un flux de sortie).
Exemple:

Code :
  1. ifstream fichierEntree( /*...*/ );
  2. double d;
  3. fichierEntree >> d;



 
Merci pour ta réponse je savais bine que je me trompais dans ma démarche ça ne pouvais pas être aussi complqiué que ça. Mais comme je suis débutant en c++ je butte encore sur la facçon d'utiliser l'opératuer par exemple je voudrais traiter un à un les éléments issus de mon fichier txtx pour les stcoker dans une classe matrice prédifini auparavant par une bibliothèque mathématique.
Par exmple le premier élément représente la dimension. Il faudrait que je le recupère et ensuite qu'il définisse la dimension grace au code :  
element1 représente ici le premier element issu de moin fichier .txt en l'occurence dans l'exemple ci-dessus : 3  

Code :
  1. ArrayLengthSpecifier dimension(element1);
  2. cout << element1 << endl;
  3. SymmetricMatrix covariance(element1);


 
Puis pour les autres éléments je voudrais les stocker dans la matrice :  
 

Code :
  1. covariance(i,j)


 
Bien sur SymmetricMatrix est déjà défini dans une librairie attaché à mon projet.
 
Peux-tu m'aider car vraiment je butte sur cette partie?
 
Merci

n°1421472
franceso
Posté le 07-08-2006 à 14:13:48  profilanswer
 

Par exemple pour la lecture de la taille de ta matrice, tu devrais remplacer les lignes suivantes

Citation :

Code :
  1. ligne = new char[10];
  2. fichierEntree.getline(ligne, 4);
  3. int conv1 = strtoul(ligne,0,10);
  4. ArrayLengthSpecifier dimension(conv1);



par une simpel utilisation de l'opérateur >> :

Code :
  1. int conv1;
  2. fichierEntree >> conv1;
  3. ArrayLengthSpecifier dimension(conv1);


 
Apres, pour remplir la matrice, c'est pareil : il te suffit de lire tes nombres un par un dans le fichier. En gros ça te donnera quelque chose dans ce style là :

Code :
  1. /* boucle sur i */
  2. for( i=0 ; /*...*/ ; /*...*/ )
  3. {
  4.   /* boucle sur j */
  5.   for( j=0 ; /*...*/ ; /*...*/ )
  6.   {
  7.     fichierEntree >> covariance(i,j);
  8.   }
  9. }


---------------
TriScale innov
n°1421478
iamora
Posté le 07-08-2006 à 14:19:32  profilanswer
 

franceso a écrit :

Par exemple pour la lecture de la taille de ta matrice, tu devrais remplacer les lignes suivantes

Citation :

Code :
  1. ligne = new char[10];
  2. fichierEntree.getline(ligne, 4);
  3. int conv1 = strtoul(ligne,0,10);
  4. ArrayLengthSpecifier dimension(conv1);



par une simpel utilisation de l'opérateur >> :

Code :
  1. int conv1;
  2. fichierEntree >> conv1;
  3. ArrayLengthSpecifier dimension(conv1);


 
Apres, pour remplir la matrice, c'est pareil : il te suffit de lire tes nombres un par un dans le fichier. En gros ça te donnera quelque chose dans ce style là :

Code :
  1. /* boucle sur i */
  2. for( i=0 ; /*...*/ ; /*...*/ )
  3. {
  4.   /* boucle sur j */
  5.   for( j=0 ; /*...*/ ; /*...*/ )
  6.   {
  7.     fichierEntree >> covariance(i,j);
  8.   }
  9. }



 
merci pour ta réponse. Effectivement c'est ce que j'ai commencé à faire je te tiens au courant et encore merci pour ton aide

n°1421503
iamora
Posté le 07-08-2006 à 14:40:19  profilanswer
 

Par contre au niveau des boucles ça coince toujours, voilà ce que j'ai mis, mais apparament il n'arrive pas à lire l'élément (i,j) = (2,2) = 1.26E-02
Je dois me tromper dans la mise en place des boucles, mais pour moi ca devrai marcher, qu'en penses-tu???
 
 

Code :
  1. #include "essai.h"
  2. #include <iostream>
  3. #include <sstream>
  4. #include <fstream>
  5. #include <iomanip>
  6. #include <string>
  7. using namespace std;
  8. int main()
  9. {
  10. ifstream FichierMatrice("c:\\test1.txt",ios::in);
  11. if (!FichierMatrice)
  12. {
  13.  cerr << "Ouverture du fichier impossible" << endl;
  14.  exit(1);
  15. }
  16. double val;
  17. double valj;
  18. int val1;
  19. int i = 0;
  20. FichierMatrice >> val1;
  21. ArrayLengthSpecifier dimension(val1);
  22. SymmetricMatrix covariance(dimension);
  23. cout << val1 << endl;
  24. do
  25. {
  26. i = i + 1;
  27. for (int j=1;j<=i;j++);
  28. {
  29. FichierMatrice >> covariance(i,j);
  30. cout << covariance(i,j) << endl;
  31. cout << covariance(j,i) << endl;
  32. }
  33. }
  34. while (!FichierMatrice.eof());
  35. return 0;
  36. }

n°1421518
franceso
Posté le 07-08-2006 à 14:49:50  profilanswer
 

Est-ce que c'est normal que tes indices i,j commencent à 1 ?
 
Que veux tu dire par "il n'arrive pas à lire l'élément (2,2)" ? Qu'est-ce qui se passe juste avant l'erreur ; qu'est-ce qui se passe au moment où tu tentes de lire l'élément (2,2) ?
 
Pourquoi ta boucle en i n'est-elle pas un simple for( int i=1 ; i<=val1 ; ++i ) ?


---------------
TriScale innov
n°1421540
iamora
Posté le 07-08-2006 à 15:05:04  profilanswer
 

franceso a écrit :

Est-ce que c'est normal que tes indices i,j commencent à 1 ?
 
Oui c'est normal ma matrice covariance est définie à partir de l'élément (1,1).
 
Que veux tu dire par "il n'arrive pas à lire l'élément (2,2)" ? Qu'est-ce qui se passe juste avant l'erreur ; qu'est-ce qui se passe au moment où tu tentes de lire l'élément (2,2) ?
 
Lorsque j'affiche le résultat sur la fenêtr dos (cette manipumation est du au fait que je ne peux pas déboguer mon code en le parcourant  ligne à ligne pour des raisons que j'ignore??) c'est pour ça que je met des cout partput c'est pour voir à quel niveau il se plante alors en mettant le code suivant  
[code]
#include "essai.h"
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <string>
 
using namespace std;
 
 
 
int main()
{
 ifstream FichierMatrice("c:\\test1.txt",ios::in);
 if (!FichierMatrice)
 {
  cerr << "Ouverture du fichier impossible" << endl;
  exit(1);
 }
 double val;
 int val1;
 int i = 0;
 
 FichierMatrice >> val1;
 ArrayLengthSpecifier dimension(val1);
 SymmetricMatrix covariance(dimension);
 cout << val1 << endl;  
 
 do  
 {
 i = i + 1;  
 for (int j=1; j<=i; j++);
 {
 FichierMatrice >> val;
 cout << val << endl;
 covariance(i,j) = val;
 cout << covariance(i,j) << endl;
 cout << covariance(j,i) << endl;
 }
 }
 while (!FichierMatrice.eof());
 return 0;
}
 
[code]
 
Il plante dans les boucles à i=2 et à j= 2.
En elevant les cout<<covariance(i,j)<<endl il ne plante pas du tout et sort tout les éléments.
 
Pourquoi ta boucle en i n'est-elle pas un simple for( int i=1 ; i<=val1 ; ++i ) ?


Je ne pense pas que ça chnage grand chose en comparaisant avec le do.
 
N'hésite pas si tu as d'autres question ça me permet de vérifier de mon côté si je suis sur la bonne voie, Je pense que ça vient du fait qu'un à moemnt covariance(i,j) est mal incrementrée???  
 
 

n°1421561
franceso
Posté le 07-08-2006 à 15:22:00  profilanswer
 

Hmm, tout cela ressemble fort à une erreur de segmentation...
 
Peux-tu me dire un peu mieux comment marche ta classe SymmetricMatrix ? C'est toi qui l'as programmée, ou elle vient d'une bibliothèque extérieure déjà testée ?
 
Si tu enlèves uniquement la ligne cout << covariance(j,i) << endl; (mais pas le cout << covariance(i,j) ) est-ce que ça plante ou pas ?


---------------
TriScale innov
n°1421589
iamora
Posté le 07-08-2006 à 15:44:59  profilanswer
 

franceso a écrit :

Hmm, tout cela ressemble fort à une erreur de segmentation...
 
Peux-tu me dire un peu mieux comment marche ta classe SymmetricMatrix ? C'est toi qui l'as programmée, ou elle vient d'une bibliothèque extérieure déjà testée ?
 
Si tu enlèves uniquement la ligne cout << covariance(j,i) << endl; (mais pas le cout << covariance(i,j) ) est-ce que ça plante ou pas ?


 
Oui, oui ca plante toujours, mais la classe SymmetricMatrix est bien définie car je la teste autre part et ça marche donc cela ne vient pas de sa définition d'utant plus que comme elle est définie comme étant une matrice symétrique .
Le test avec cout << covariance(j,i) << sert seulement à voir si elle marche bien mais comme c'est le cas des deux premier éléments je ne me pose pas trop de questions la dessus je pense plutôt que c'est une errreur d'incrémentation de boucle.  
 

mood
Publicité
Posté le 07-08-2006 à 15:44:59  profilanswer
 

n°1421653
iamora
Posté le 07-08-2006 à 16:36:33  profilanswer
 

franceso a écrit :

Hmm, tout cela ressemble fort à une erreur de segmentation...
 
Peux-tu me dire un peu mieux comment marche ta classe SymmetricMatrix ? C'est toi qui l'as programmée, ou elle vient d'une bibliothèque extérieure déjà testée ?
La classe SymmetricMatrix est bien définie je l'ai pris de la bibliothèque Newmat et je l'ai testé autre part (pas de problème elle marche) Je pense que cela ne vient pas de sa définition  
 
 
Si tu enlèves uniquement la ligne cout << covariance(j,i) << endl; (mais pas le cout << covariance(i,j) ) est-ce que ça plante ou pas ?


 
Le test avec cout << covariance(j,i) << sert seulement à voir si elle marche bien mais comme c'est le cas des deux premier éléments je ne pense que cela vienne de la classe SmmetricMatrix.
 
Par contre j'ai remplacé le <= de la boucle j par le < tout court et bizarrement ça compile jusqu'à l'élément (3,1) en tenant compte de l'élément (2,1).
Je ne comprend pas la raison ???

n°1421668
franceso
Posté le 07-08-2006 à 16:46:26  profilanswer
 

iamora a écrit :

Par contre j'ai remplacé le <= de la boucle j par le < tout court et bizarrement ça compile jusqu'à l'élément (3,1) en tenant compte de l'élément (2,1).
Je ne comprend pas la raison ???

Tu veux dire que le programme tourne jusqu'à i=3, j=1  et met dans covariance(3,1) la valeur que tu t'attendrais à avoir dans covariance(2,2) ?
 
La raison est que tel que ton programme est écrit, il ne tient pas compte de l'agencement des données dans le fichier. Il lit juste la suite des valeurs dans l'ordre sans se soucier de la ligne sur laquelle elles sont. Du coup, si ta boucle saute directement de 2,1 à 3,1 la valeur mise dans 3,1 est celle qui suit immédiatement la valeur mise dans 1,2. J'ai l'impression de ne pas être très clair, mais je ne sais pas trop comment l'expliquer mieux.


---------------
TriScale innov
n°1421685
iamora
Posté le 07-08-2006 à 17:05:26  profilanswer
 

franceso a écrit :

Tu veux dire que le programme tourne jusqu'à i=3, j=1  et met dans covariance(3,1) la valeur que tu t'attendrais à avoir dans covariance(2,2) ?
 
La raison est que tel que ton programme est écrit, il ne tient pas compte de l'agencement des données dans le fichier. Il lit juste la suite des valeurs dans l'ordre sans se soucier de la ligne sur laquelle elles sont. Du coup, si ta boucle saute directement de 2,1 à 3,1 la valeur mise dans 3,1 est celle qui suit immédiatement la valeur mise dans 1,2. J'ai l'impression de ne pas être très clair, mais je ne sais pas trop comment l'expliquer mieux.


 
En fait que veut tu dire par "Il lit juste la suite des valeurs dans l'ordre " est ce par ordre croissant comment marche  >> ???
J'ai remarqué en testant que pour mon programme  
covariance(1,2) est équivalent à l'élément (1,1)
covariance(2,3) ou covariance(3,2) est équivalent à l'élément (2,1)  
covariance(3,4) est équivalent à l'élément (2,2)  
Je ne sais pas pourquoi il saute comme ça??


Message édité par iamora le 07-08-2006 à 17:07:12
n°1421694
iamora
Posté le 07-08-2006 à 17:14:31  profilanswer
 

franceso a écrit :

Tu veux dire que le programme tourne jusqu'à i=3, j=1  et met dans covariance(3,1) la valeur que tu t'attendrais à avoir dans covariance(2,2) ?
 
La raison est que tel que ton programme est écrit, il ne tient pas compte de l'agencement des données dans le fichier. Il lit juste la suite des valeurs dans l'ordre sans se soucier de la ligne sur laquelle elles sont. Du coup, si ta boucle saute directement de 2,1 à 3,1 la valeur mise dans 3,1 est celle qui suit immédiatement la valeur mise dans 1,2. J'ai l'impression de ne pas être très clair, mais je ne sais pas trop comment l'expliquer mieux.


 
Bon je vois ce que tu veux dire. Est ce que je peux par changer le code de telle façon à ce que val stocke les valeurs qu'elle prend dans des adresses qui se suivent grâce à une boucle genre un tableau puis dire à covariance(i,j) de prendre ses valeurs???


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

  Problème sur un flux de lecture à partir d'un fichier .txt

 

Sujets relatifs
probleme iframe easyphpprobleme avec foreach
Batch - Obtenir le poids d'un fichier avec la commande ForFile.exe[PHP] Upload de fichier presque fonctionnel (presk...)
Batch - Afficher les fichier du répertoire System Volume InformationPetit problème avec un script qui test la date d'installation de windo
[Javascript] Problème d'espace et <select> [Résolu][SQL Server 2005] Problème de création de fonction
Problème avec -OEffacer la mise en forme d'un fichier
Plus de sujets relatifs à : Problème sur un flux de lecture à partir d'un fichier .txt


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