lire des float dans un .txt

lire des float dans un .txt - C - Programmation

Marsh Posté le 26-04-2006 à 11:40:37    

Bonjour,
voila, ça fait un moment que j'suis dessus a que ça bug dans tout les sens, alors je viens vous solliciter pour un peu d'aide.

 

Probleme :

 

Je dispose d'un fichier .txt, contenant une matrice de float entre 0 et 1.
Exemple :

1.000000,0.812725,0.782864,0.732827,0.678602,0.781187,0.743800,0.595378,0.854859
,0.712598,0.637022,0.600580,0.868002 etc...  

 

Donc les différentes valeurs sont séparés par des virgules, comme vous avez pu le voir.
Mon but (a ce stade), et de lire ce fichier pour obtenir un tableau 2dim de float que je puisse ensuite manipuler comme bon me semble.
Mon probleme : je n'arrive pas a lire ce fichier comme il faut.

 

J'ai essayer avec :

Code :
  1. fscanf(f,"%f",&var);


Mais ça plante.
J'ai essayer a coup de fgets/fgetc, et de cast le tout ensuite, mais le probleme ce situe au niveau du cast, je n'arrive pas a recuperer la partie flottante correctement (mise a 0 lors du cast).

 

Bref, j'suis un peu perdu dans le sfonction que je pourrai utilisé, pour obtenir du float a partir de ce fichier .txt.

 

J'ai essayer de l'ouvrir en binaire pour recup des float mais ça deconne pas mal...

 

Si vous avez des suggestions...n'hesitez pas!!

 

Merci!
 
 

  


Reply

Marsh Posté le 26-04-2006 à 11:40:37   

Reply

Marsh Posté le 26-04-2006 à 11:43:38    

Reply

Marsh Posté le 26-04-2006 à 11:53:01    


 
Le probleme, c'est qu'avec atof, je perd ma partie flottante (d'apres ce que j'ai constater).
Si j'ia une chaine :  
char str="0.169083"
j'obtient du "0.000000"
 
 :pfff:  
 
 
Mais merci pour strok, je ne connaissant pas et ça pourra p-e bien me servir si j'arrive a une conversion correct.

Reply

Marsh Posté le 26-04-2006 à 11:56:32    

Reply

Marsh Posté le 26-04-2006 à 11:56:46    

Heu j'ai rien dit a propos du cast, en faisant un test independant de mon fichier, j'ai bien obtenu ce que je voulais...
 
donc je vais re-essayer

Reply

Marsh Posté le 26-04-2006 à 11:58:40    

lis ligne par ligne
 
pour chaque ligne fait une boucle:
 
strtod + sauter la ','
 
 
gaffe aux locales aussi

Reply

Marsh Posté le 26-04-2006 à 12:17:37    

Taz a écrit :

lis ligne par ligne
 
pour chaque ligne fait une boucle:
 
strtod + sauter la ','
 
 
gaffe aux locales aussi


Je m'interroge sur la meilleur maniere de recuper une ligne d'un coup.
une fonction approprier a ça?
 
Sachant que une ligne de mon fichier txt et censé correspondre a une ligne de ma matrice, mais que ça depasse apparament la longueur max qu'une ligne peut avoir, car elle est en faite sur 2 (vois plus celon les fichiers) lignes.
Je ne sais pas s'il y a un caractere de fin de ligne ou pas dans ces conditions?(il y en a un a la fin de la ligne de la matrice, ça c'est certain)

Reply

Marsh Posté le 26-04-2006 à 12:26:00    

gargantua307 a écrit :

Je m'interroge sur la meilleur maniere de recuper une ligne d'un coup.


fgets(), c'est fait pour
 
http://mapage.noos.fr/emdel/notes.htm#saisie
http://mapage.noos.fr/emdel/notes.htm#fichiers


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 26-04-2006 à 12:35:44    


 
 
Ben le probleme c'est qu ej'ai besoin de la longueur de la ligne, or celle-ci peut etre variable (soit "pleine"(=max de car pour un fihcier txt sur une ligne), soit inferieur...et ça depend du fichier que j'ouvre (et il faut bien sur que ça marche pour tous )
 :heink:  :??:

Reply

Marsh Posté le 26-04-2006 à 13:08:03    

gargantua307 a écrit :

Ben le probleme c'est qu ej'ai besoin de la longueur de la ligne, or celle-ci peut etre variable (soit "pleine"(=max de car pour un fihcier txt sur une ligne), soit inferieur...et ça depend du fichier que j'ouvre (et il faut bien sur que ça marche pour tous )
 :heink:  :??:


 
Si tu le connais le max, c'est OK.
 
Sinon, il faut te faire une fonction de lecture 'souple' (malloc(), realloc()...). C'est un peu plus rusé...
 
J'ai une solution industrielle un peu, disons, 'avancée'...
 
http://mapage.noos.fr/emdel/clib.htm
Module IO


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 26-04-2006 à 13:08:03   

Reply

Marsh Posté le 27-04-2006 à 14:53:38    

Bonjour,
 
 
bon je me suis remis sur mon prog et j'ai un souci (toujours).
En faite, j'arrive un peu pret a lire mon fichier(il ya a juste le saut de ligne qu'il faut que je gere), en utilisant fgets pour recup ligne / ligne les infos, et traitant la chaine avec strok et atof.
VOici mon code (extrais) :  
 

Code :
  1. f=fopen(str,"r+" )                                    /* ouverture du fichier */
  2. for(i=0;i<nb;i++)                                    /* pour chaque ligne */
  3. {
  4.    fgets(strTmp,(nb+nb-1),f);                 /* recupere une ligne complete */
  5.    for(j=0;j<nb;j++)                                /* pour chaque element de la ligne (=nb) */
  6.    {
  7.       strFloTmp = strtok (strTmp,"," );         /* on decoupe la chaine avec la virgule en separateur*/
  8.       tab[i][j]=atof(strFloTmp);                 /* on cast et enregostre dans un tableau 2 dim de float. */
  9.    }
  10. }
  11. fclose(f);                                             /* referme le fichier */


 
Et voici la 1ere ligne de mon fichier :  


1.000000,0.812725,0.782864,0.732827,0.678602,0.781187,0.743800,0.595378,0.854859,0.712598,
0.637022,0.600580,0.868002,0.810179,0.782958,0.907919,0.779902,0.962846,0.672705,0.737339,
...
0.334840,0.321841,0.326278,0.254191,0.391696,0.285422,0.329793,0.364168,0.384845,0.381159


 
 
Mon probleme : quand j'affiche mon tableau "tab", je n'ai que des "1.000000", soit la premiere valeur lu.
Comment resoudre le probleme???
Pourquoi n'avance t-il pas dans le fichier, ou la variable n'est-elle pas mis a jour??
 
Merci de votre aide.


Message édité par gargantua307 le 27-04-2006 à 14:58:24
Reply

Marsh Posté le 27-04-2006 à 14:58:32    

man strtok:

Citation :

The strtok() function can be used to parse the string  s  into  tokens. The  first call to strtok() should have s as its first argument. Subsequent calls should have the first  argument  set  to  NULL.  Each  call returns  a  pointer  to the next token, or NULL when no more tokens are found


 
tu appelles toujours strtok avec strTmp, et c'est pour ça que tu n'avances pas dans la ligne :  tu parses toujours le premier jeton.


---------------
TriScale innov
Reply

Marsh Posté le 27-04-2006 à 14:59:29    

franceso a écrit :


tu appelles toujours strtok avec strTmp, et c'est pour ça que tu n'avances pas dans la ligne :  tu parses toujours le premier jeton.


 
 
Effectivement!
 
Merci beaucoup :)

Reply

Marsh Posté le 27-04-2006 à 18:23:37    


 
 
J'ai reussi a lire une ligne, la traité, obtenir ce que je voulais etc.
Il me reste un dernier bug que je n'arrive pas a supprimer.
 
Quand je veux passer a la deuxieme ligne, mon prog plante sur le fgets.
Je ne sais pas pourquoi.
j'ai essayer d'augmenter la longueur max lu pour etre sur que le \n etais bien lu, meme resultat.
J'ai essayer de faite un fgetc, meme resultat.
J'ai essayer de faire un fflush, meme resultat.
 
Je ne sais plus quoi faire...
 
Merci encore de votre aide precieuse.

Reply

Marsh Posté le 27-04-2006 à 18:31:13    

gargantua307 a écrit :

J'ai reussi a lire une ligne, la traité, obtenir ce que je voulais etc.
Il me reste un dernier bug que je n'arrive pas a supprimer.
 
Quand je veux passer a la deuxieme ligne, mon prog plante sur le fgets.


il faut toujours tester la valeur retournée par les fonction de lecture. C'est elle qui determine si on a une fonc de lecture... La méthode canonique pour fgets() est :  

Code :
  1. if (fp != NULL)
  2.    {
  3.       char line[123];
  4.       while (fgets(line, sizeof line, fp) != NULL)
  5.       {
  6.          /* traitement */
  7.       }



---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-04-2006 à 18:41:29    

Emmanuel Delahaye a écrit :

il faut toujours tester la valeur retournée par les fonction de lecture. C'est elle qui determine si on a une fonc de lecture... La méthode canonique pour fgets() est :  

Code :
  1. if (fp != NULL)
  2.    {
  3.       char line[123];
  4.       while (fgets(line, sizeof line, fp) != NULL)
  5.       {
  6.          /* traitement */
  7.       }



Si j'ai bien compris
Données :  


1.000000,0.812725,0.782864,0.732827,0.678602,0.781187,0.743800,
0.595378,0.854859,0.712598,0.637022,0.600580,0.868002
 


Code :  

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main(void)
  4. {
  5.    FILE *fp = fopen("data.txt", "r" );
  6.    if (fp != NULL)
  7.    {
  8.       char line[123];
  9.       while (fgets(line, sizeof line, fp) != NULL)
  10.       {
  11.          /* traitement */
  12.          printf ("%s", line);
  13.          char *p = line;
  14.          while (*p != 0)
  15.          {
  16.             double n = strtod(p, &p);
  17.             printf ("%f\n", n);
  18.             p++;
  19.          }
  20.       }
  21.       fclose (fp);
  22.    }
  23.    return 0;
  24. }


 
Ca recommence les délires avec les blocs 'code'...  

  • Couleurs bizarres,  
  • '\n' qui devient 'n'


Message édité par Emmanuel Delahaye le 27-04-2006 à 18:47:42

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-04-2006 à 18:41:57    

Ben en faite, il me plante vraiment a la gueule.
Meme avec un while(fprintf(..)!=NULL) il plante a l'execution sans que je puisse faire quoi que ce soit d'autre.
 
D'ailleur si quelqu'un sait comment capturer les erreurs sur un projet fait avec VC++ en MFC... je ne sait pas de quel type elles sont.
 
 
Autre probleme, tout a l'heure j'ai remarquer que mon fclose du fichier planter lui aussi (depuis peu).
J'avais fait une erreur a un moment en faisant un fprintf sur le mauvais fichier (donc sur celui que j'ai en lecture), c'est dpeuis que j'ai observé que le fclose planté (la encore, impossible de traiter le retour de la fonction).
J'ai redemarrer etc, rien n'y fait.

Reply

Marsh Posté le 27-04-2006 à 18:46:50    

gargantua307 a écrit :

J'avais fait une erreur a un moment en faisant un fprintf sur le mauvais fichier (donc sur celui que j'ai en lecture),


C'est sûr que si tu fais un fprintf() sur un fichier en lecture, ça va morfler...
 
Efface ton fichier douteux.
 
Et poste ton code, qu'on y voit clair...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-04-2006 à 18:52:53    

Voici ma fonction en entiere (certain truc ne sont pas tres beau et temporaire en "debugage", mais c'est a force de bidouillage...je referai un peu le propre apres).
 

Code :
  1. float** LireMatrice (CString str, int nb)
  2. {
  3. FILE* f;
  4. int i=0,j=0,ent=0,bool=0;
  5. float** tab;
  6. char* strTmp;
  7. char* strFloTmp;
  8. if (strTmp=(char*)malloc(sizeof(char)*(nb*2)))
  9. {
  10. //allocation dynamique du tableau 2 dimensions
  11. if(tab=(float**)malloc(sizeof(float*) * nb))
  12. {
  13.  bool=1;
  14.  j=0;
  15.  while (j<nb && bool==1)
  16.  {
  17.   bool=0;
  18.   j++;
  19.   if (tab[i]=(float*)malloc(sizeof(float)*nb))
  20.    bool=1;
  21.  }
  22. }
  23. if(bool==1) // si l'allocation a reussi
  24. {
  25.  if (f=fopen(str,"r" )) // si ouverture du fichier reussi
  26.  {
  27.   i=0;
  28.   while((i<1) && (fgets(strTmp,(sizeof(char)*((8*nb)+nb)),f)!=NULL))  //lit une ligne du fichier
  29.   {
  30.    strFloTmp = strtok(strTmp,"," );
  31.    tab[i][0]=atof(strFloTmp);
  32.    for(j=1;j<nb;j++)
  33.    {
  34.     strFloTmp=strtok(NULL,"," );
  35.     if (strFloTmp!=NULL)
  36.     {
  37.      tab[i][j]=atof(strFloTmp);
  38.     }
  39.    }
  40.    i++;
  41.   }
  42.   fclose(f);
  43.   return tab;
  44.  }
  45.  else /* ouverture du fichier impossible */
  46.  {
  47.   free(tab);
  48.   return NULL;
  49.  }
  50. }
  51. else /* impossible d'allouer la memoire necessaire pour la matrice */
  52. {
  53.  AfxMessageBox("echec alloc matrice" );
  54.  free(strTmp);
  55.  free(tab);
  56.  return NULL;
  57. }
  58. }
  59. else
  60. {
  61.  AfxMessageBox("echec alloc strTmp" );
  62.  return NULL; // impossible d'allour la memoire pour la chaine temporaire
  63. }
  64. }

Message cité 2 fois
Message édité par gargantua307 le 27-04-2006 à 18:54:53
Reply

Marsh Posté le 27-04-2006 à 18:55:23    

gargantua307 a écrit :


Code :
  1. float** LireMatrice (CString str, int nb)



C'est quoi CString ?
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 27-04-2006 à 18:56:49    

Emmanuel Delahaye a écrit :

C'est quoi CString ?


 
C'est ce que me renvoi mon champ 'edit' de mon interface.
Mais il est converti implicitement en char* sans probleme.
 
edit : interface en C++

Message cité 1 fois
Message édité par gargantua307 le 27-04-2006 à 18:57:51
Reply

Marsh Posté le 27-04-2006 à 19:11:06    

A noter que je viens d'essayer avec d'autre fichier (pour mon histoire du fclose qui plante), et ça fait la meme chose...!
 
Alors est-ce que par hasard qq chose pourrait corrompre le stream du fichier ouvert et tout faire planter donc?

Reply

Marsh Posté le 27-04-2006 à 19:20:11    

passe le debugger, vérifie tes variables, vérifie que tu dois rien flusher ...

Reply

Marsh Posté le 28-04-2006 à 00:53:21    

Si tu es en MFC, tu fais du C++ et les malloc/free ne sont pas forcément du meilleur effet !

Reply

Marsh Posté le 28-04-2006 à 09:41:52    

Trap D a écrit :

Si tu es en MFC, tu fais du C++ et les malloc/free ne sont pas forcément du meilleur effet !


 
Bah, les malloc sont casté, donc a priori pas de probleme.
 
Mais en faite il n'y a que mon interface en C++, le reste je prog en C. (sauf le param CString, j'avoue que j'ai eu la flem de le convertir avant puisque ça marche...).
 
 
Bon, sinon si je ne lis qu'une seul ligne, je sort de ma fonction niquel, donc j'retourne sur ma fonction "principale", et j'en sort (donc j'arrive dans ma fonction "OnClikButton" d'ou est d'éclenché tout ça, je ne plus rien apres, et PAF, c'est la que ça plante. Alors la j'ai du mal a pigé...plus rien, sort sans probleme apparent (la trace fonctionne bien), et ça plante...?
 
 
Et sinon je n'arrive toujours pas a passé a ma deuxieme ligne >_<
Ce qui est tres embettant.

Reply

Marsh Posté le 28-04-2006 à 09:48:41    

use the force, use the debugger


---------------
Töp of the plöp
Reply

Marsh Posté le 28-04-2006 à 09:56:31    

_darkalt3_ a écrit :

use the force, use the debugger


 
Ben l edebugger m'aide pas trop (je sais pas bien m'en servir non plus)
J'obtient ce message, mais je ne sais pas a quel niveau du code vu qu'il me pointe sur le code en assembleur.
 
http://gargant.info/divers/bug_boucle.JPG

Reply

Marsh Posté le 28-04-2006 à 09:59:09    

gargantua307 a écrit :

Bah, les malloc sont casté, donc a priori pas de probleme.


 
On en a pendu pour moins que ça :o
Soit tu fais du C soit tu fais du C++
 
Et bon en C++ avec un boost::tokenizer et des flux, c'est torché en 20 lignes ...

Reply

Marsh Posté le 28-04-2006 à 10:02:49    

gargantua307 a écrit :

Ben l edebugger m'aide pas trop (je sais pas bien m'en servir non plus)


 
it's time to learn.


Message édité par _darkalt3_ le 28-04-2006 à 10:03:22

---------------
Töp of the plöp
Reply

Marsh Posté le 28-04-2006 à 10:03:17    

Citation :


Soit tu fais du C soit tu fais du C++


 
Rien n'empeche d'utiliser du code C en C++.
Mais c'est une contrainte qu'on m'impose de rester en C.
Mais la langage de l'interface est libre.
Je ne savais pas faire d'interface, j'ai appris a utiliser l'IDE de VC++ et les MFC.  
Donc voila...
 
Mais dans tout les cas, mon probleme sur la lecture du fichier reste le meme...
Et pius bon, les malloc me retourne bien ce que j'attend.

Message cité 2 fois
Message édité par gargantua307 le 28-04-2006 à 10:04:10
Reply

Marsh Posté le 28-04-2006 à 10:04:21    

gargantua307 a écrit :

Rien n'empeche d'utiliser du code C en C++.


Si: le bon sens.


---------------
Töp of the plöp
Reply

Marsh Posté le 28-04-2006 à 10:05:54    

_darkalt3_ a écrit :

Si: le bon sens.


 
Pas d'accord.
Si on devait se limiter a un seul langage a chaque projet...

Message cité 1 fois
Message édité par gargantua307 le 28-04-2006 à 10:06:11
Reply

Marsh Posté le 28-04-2006 à 10:14:16    

gargantua307 a écrit :

Pas d'accord.
Si on devait se limiter a un seul langage a chaque projet...


 
limitons nous à un seul langage par objet, et dans ton cas par fonction !


Message édité par _darkalt3_ le 28-04-2006 à 10:14:50

---------------
Töp of the plöp
Reply

Marsh Posté le 28-04-2006 à 10:15:28    

gargantua307 a écrit :

Voici ma fonction en entiere (certain truc ne sont pas tres beau et temporaire en "debugage", mais c'est a force de bidouillage...je referai un peu le propre apres).
 

Code :
  1. float** LireMatrice (CString str, int nb)
  2. {
  3. FILE* f;
  4. int i=0,j=0,ent=0,bool=0;
  5. float** tab;
  6. char* strTmp;
  7. char* strFloTmp;
  8. if (strTmp=(char*)malloc(sizeof(char)*(nb*2)))
  9. {
  10. //allocation dynamique du tableau 2 dimensions
  11. if(tab=(float**)malloc(sizeof(float*) * nb))
  12. {
  13.  bool=1;
  14.  j=0;
  15.  while (j<nb && bool==1)
  16.  {
  17.   bool=0;
  18.   j++;
  19.   if (tab[i]=(float*)malloc(sizeof(float)*nb))
  20.    bool=1;
  21.  }
  22. }
  23. if(bool==1) // si l'allocation a reussi
  24. {
  25.  if (f=fopen(str,"r" )) // si ouverture du fichier reussi
  26.  {
  27.   i=0;
  28.   while((i<1) && (fgets(strTmp,(sizeof(char)*((8*nb)+nb)),f)!=NULL))  //lit une ligne du fichier
  29.   {
  30.    strFloTmp = strtok(strTmp,"," );
  31.    tab[i][0]=atof(strFloTmp);
  32.    for(j=1;j<nb;j++)
  33.    {
  34.     strFloTmp=strtok(NULL,"," );
  35.     if (strFloTmp!=NULL)
  36.     {
  37.      tab[i][j]=atof(strFloTmp);
  38.     }
  39.    }
  40.    i++;
  41.   }
  42.   fclose(f);
  43.   return tab;
  44.  }
  45.  else /* ouverture du fichier impossible */
  46.  {
  47.   free(tab);
  48.   return NULL;
  49.  }
  50. }
  51. else /* impossible d'allouer la memoire necessaire pour la matrice */
  52. {
  53.  AfxMessageBox("echec alloc matrice" );
  54.  free(strTmp);
  55.  free(tab);
  56.  return NULL;
  57. }
  58. }
  59. else
  60. {
  61.  AfxMessageBox("echec alloc strTmp" );
  62.  return NULL; // impossible d'allour la memoire pour la chaine temporaire
  63. }
  64. }



 
Tout tester (malloc, fopen, etc), c'est bien. C'est très bien en fait. Le pb, c'est que ta façon de tester te conduit à des if/else de folie. Et ton code "utile" se trouve totalement décalé.
C'est plus courant d'utiliser le style suivant
1) je fais un truc, je le teste et si ça plante je sors de la fonction
2) je passe au truc suivant
3) arrivé à ce point, je suis certain que tout est bon donc je peux coder tranquille => ça évite les "bool=1" etc... et ça permet de coder tout de suite la gestion de l'erreur (et non dans un lointain "else" 3 pages plus bas)
 
Ta fonction avec la gestion des erreurs réécrite

Code :
  1. float** LireMatrice (CString str, int nb)
  2. {
  3. FILE* f;
  4. int i=0,j=0,ent=0,bool=0;
  5. float** tab;
  6. char* strTmp;
  7. char* strFloTmp;
  8. // Allocation strTmp  
  9. if ((strTmp=(char*)malloc(sizeof(char)*(nb*2))) == NULL)    // Pourquoi "nb * 2" ???
  10. {
  11.  // Allocation échouée
  12.  return NULL;
  13. }
  14. // Allocation matrice
  15. if ((tab=(float**)malloc(sizeof(float*) * nb)) == NULL)
  16. {
  17.  // Allocation matrice échouée
  18.  free(strTmp);
  19.  return NULL;
  20. }
  21. for (i=0; i < nb; i++)
  22. {
  23.  if ((tab[i]=(float*)malloc(sizeof(float) * nb)) == NULL)        // Pourquoi "* nb" ???
  24.  {
  25.   // Allocation élément échoué
  26.   for (j=0; j < i; j++)
  27.    free(tab[j]);
  28.   free(tab);
  29.   free(strTmp);
  30.   return NULL;
  31.  }
  32. }
  33. // Ouverture fichier
  34. if ((fp=fopen(str, "r" )) == NULL)
  35. {
  36.  // Ouverture échouée
  37.  for (i=0; i < nb; i++)
  38.   free(tab[i]);
  39.  free(tab);
  40.  free(strTmp);
  41.  return NULL;
  42. }
  43. // Lecture du fichier etc...
  44. while (...)
  45. // Libération des ressources
  46. fclose(fp);
  47. free(strTmp);
  48. // Renvoi tableau
  49. return tab;
  50. }


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 28-04-2006 à 10:28:03    

Merci bien.
J'ai tendance a prendre la mauvaise approche a chaque fois il est vrai.
 
 
 
Alors sinon :  
pour :  

if ((strTmp=(char*)malloc(sizeof(char)*(nb*2))) == NULL)    // Pourquoi "nb * 2" ???


strTmp me sert a recuperer un ligne complete de mon fichier.  
En faite j'avais oublier un p'tit details lorsque j'ai posté la fonction, mais actuellement la ligne est :

if ((strTmp=(char*)malloc(sizeof(char)*((8*nb)+nb)))=NULL)


nb est le nombre d'élément / ligne. Ces élément on une longueur de 8. Il sont separer par des virgules (donc nb-1 virgule), et j'ajoute une place pour le car de saut de ligne '\n'.
J'ai donc une espace alloué pile poil a la longueur de ce que je lis.
 

if ((tab[i]=(float*)malloc(sizeof(float) * nb)) == NULL)        // Pourquoi "* nb" ???


tab et un tableau 2 dim, qui est donc alloué dynamiquement.
nb et le nombre d'élément par ligne de ce tableau, ceci placé dans la boucle me permet d'allouer l'espace necessaire pour chaque ligne. La longueur des colonnes ayant deja etais aloué juste avant.
Note : il me semble que le C inverse les lignes/colonnes tels que j'ai les ai decrites, mais le resultat est identiques (quoiqu'il faudrait que j'ai repense pour une optimisation de temps).
 
 
 

Reply

Marsh Posté le 28-04-2006 à 10:32:00    

gargantua307 a écrit :

Citation :


Soit tu fais du C soit tu fais du C++


Rien n'empeche d'utiliser du code C en C++.


Qu'est-ce que tu en sais ? Tu connais toutes les subtilités des deux langages ?
 
http://david.tribble.com/text/cdiffs.htm

Citation :


Mais c'est une contrainte qu'on m'impose de rester en C.


Alors adieu MFC... Interesse toi à GTK+. en plus, c'est portable...


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 28-04-2006 à 10:58:57    

Emmanuel Delahaye a écrit :

Qu'est-ce que tu en sais ? Tu connais toutes les subtilités des deux langages ?
http://david.tribble.com/text/cdiffs.htm

Citation :


Mais c'est une contrainte qu'on m'impose de rester en C.


Alors adieu MFC... Interesse toi à GTK+. en plus, c'est portable...


 
 
Non, je ne serait pas arrogant a dire que je connait toutes les subtilités entre le C/C++.
Mais j'ai deja parcouru une liste d'incompatibilité comme celle que tu as indiqué, et n'y voit pas de probleme par rapport a mon code.
D'autant plus que je ne melange pas C++ et C dans une meme fonction, et que ma partie C et clairement separer du C++ (toujours exception faite du CString qui le compilo gere tout seul, mais si ça te fait plaisir je le cast avant).
 
 
Concernet GTK+, existe-t-il des IDE dessus?  
Car j'étais intéressé, mais l'interface de mon prog n'etant pas vraiment important pour ce projet, je ne voulais pas me prendre la tete a coder l'interface integralement. C'est pour ça que j'ai opté pour le MFC, ou je peut creer l'interface en quelque clic avec VC++.
 
Il y a aussi le fait que je vais devoir créer une image a la fin (enfin sinon je vois pas bien comment faire) pour representer une grille, avec differentes couleurs, et la bibliotheque que l'on m'a indiquer et en C++ si je me souvient bien.

Reply

Marsh Posté le 28-04-2006 à 11:22:38    

Bon, alors que je ne faisait que re-ecrire ma fonctoin pour une meilleur lisibilité, et bien tout mes probleme on disparu.
Plus aucune erreur, et le traitement que je voulais effectué.
Il devait donc bien y avoir une p'tite erreur quelque part.
 
 
En tout cas merci a tous.
 
Voici la fonction maintenant :  
 

Code :
  1. float** LireMatrice (CString str, int nb)
  2. {
  3. FILE* f;
  4. int i=0,j=0,ent=0,bool=0;
  5. float** tab;
  6. char* strTmp;
  7. char* strFloTmp;
  8. //allocation dynamique de la chaine temporaire pour la lecture du fichier
  9. if ( (strTmp=(char*)malloc(sizeof(char)*((8*nb)+nb+1)))==NULL )
  10. {
  11.  return NULL;
  12. }
  13. //allocation dynamique du tableau 2 dimensions
  14. if( (tab=(float**)malloc(sizeof(float*)*nb))==NULL)
  15. {
  16.  free(strTmp);
  17.  return NULL;
  18. }
  19. for(i=0;i<nb;i++)
  20. {
  21.  if( (tab[i]=(float*)malloc(sizeof(float)*nb))==NULL)
  22.  {
  23.   free(strTmp);
  24.   for(j=0;j<i;j++)
  25.   {
  26.    free(tab[j]);
  27.   }
  28.   free(tab);
  29.   return NULL;
  30.  }
  31. }
  32. // ouverture du fichier
  33. if((f=fopen(str,"r" ))==NULL )
  34. {
  35.  free(strTmp);
  36.  for(j=0;j<i;j++)
  37.  {
  38.   free(tab[j]);
  39.  }
  40.  free(tab);
  41.  return NULL;
  42. }
  43. //lecture du fichier
  44. i=0;
  45. //recupere les données ligne/ligne
  46. while((i<nb) && (fgets(strTmp,(sizeof(char)*((8*nb)+nb+1)),f)!=NULL)) 
  47. {
  48.  //decoupe la chaine a chaque virgule et conversion en float de la sous chaine
  49.  strFloTmp = strtok(strTmp,"," );
  50.  if (strFloTmp != NULL)
  51.   tab[i][0]=(float)atof(strFloTmp);
  52.  j=1;
  53.  while((j<nb)&& (strFloTmp!=NULL))
  54.  {
  55.   strFloTmp=strtok(NULL,"," );
  56.   if (strFloTmp!=NULL)
  57.   {
  58.    tab[i][j]=(float)atof(strFloTmp);
  59.   }
  60.   j++;
  61.  }
  62.  i++;
  63. }
  64. // si strTmp == NULL -> erreur de lecture
  65. if(strTmp==NULL)
  66. {
  67.  free(strTmp);
  68.  for(j=0;j<i;j++)
  69.  {
  70.   free(tab[j]);
  71.  }
  72.  free(tab);
  73.  return NULL;
  74. }
  75. fclose(f);
  76. return tab;
  77. }

Reply

Marsh Posté le 28-04-2006 à 12:33:32    

gargantua307 a écrit :

if ((strTmp=(char*)malloc(sizeof(char)*((8*nb)+nb)))=NULL)


nb est le nombre d'élément / ligne. Ces élément on une longueur de 8. Il sont separer par des virgules (donc nb-1 virgule), et j'ajoute une place pour le car de saut de ligne '\n'.
J'ai donc une espace alloué pile poil a la longueur de ce que je lis.


 
Hum. Tout d'abord, moi je mettrais "== NULL" plutôt que "= NULL". Au pire, ça n'en fonctionnera que mieux  :D  
 
De plus, "(8 * nb) + nb" s'écrit aussi bien "8 * nb + nb" (priorité de la multiplication sur l'addition)
Par ailleurs, chaque élément, virgule compris, fait "9" donc moi je mettrais plutôt
"sizeof(char) * 9 * nb"
Surtout que "8 * nb + nb" <=> "9 * nb"
 
Enfin, tu alloues "pile poil" la longueur de ce que tu lis... mais tu as oublié la place pour y stocker "pile poil" le '\0' qui termine toute chaîne =>

if ((strTmp=(char*)malloc(sizeof(char)*(9 * nb + 1))) == NULL)

Message cité 1 fois
Message édité par Sve@r le 28-04-2006 à 12:35:40

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 28-04-2006 à 12:39:56    

Sve@r a écrit :

Hum. Tout d'abord, moi je mettrais "== NULL" plutôt que "= NULL". Au pire, ça n'en fonctionnera que mieux  :D  
 
De plus, "(8 * nb) + nb" s'écrit aussi bien "8 * nb + nb" (priorité de la multiplication sur l'addition)
Par ailleurs, chaque élément, virgule compris, fait "9" donc moi je mettrais plutôt
"sizeof(char) * 9 * nb"
Surtout que "8 * nb + nb" <=> "9 * nb"
 
Enfin, tu alloues "pile poil" la longueur de ce que tu lis... mais tu as oublié la place pour y stocker "pile poil" le '\0' qui termine toute chaîne =>

if ((strTmp=(char*)malloc(sizeof(char)*(9 * nb + 1))) == NULL)



 
 
P'tite erreur de frappe pour le = NULL ^_^
 
Sinon pour le calcul, j'ai decomposé pour une meilleur comprehension de ce que je fait, et j'ai deja remarqué qu'il me manqué un car pour le \0 et j'ai donc deja fait les modif ^_^
 
Merci quand meme pour la remarque tout a fait pertinente. :jap:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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