L'allocation mémoire ne marche pas bien

Résolu/Fermé
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017 - Modifié par geekat le 20/01/2016 à 21:47
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017 - 23 janv. 2016 à 15:55
Bonjour,
J'aimerais allouer mon fichier dans une matrice. J'ai essayé de faire ça mais le résulta est que ça m'affiche à partir de la 2ème ligne du fichier et après ça bug.
Pourquoi ?
Voici le code :
/* Fichiers d'en-tête */
#include <stdlib.h>    // Génération nbres aléatoires, allocation dynamique mémoire
#include <stdio.h>    //  Gestion erreurs et E/S (scanf, printf)
#include <math.h>  //   Fonctions mathématiques
#include <string.h>
#define TAILLE_MAX  4700
// 1ère étape : Chargement du fichier IRIS DATA ==> pas OK
int main()
 {    /* Descripteur fichier */
     FILE* fichier = NULL;
  
  /* Ouverture fichier */
     fichier = fopen("iris_data.txt", "r+");
 
     if (fichier != NULL)
     {
      char chaine[TAILLE_MAX] = ""; // Chaîne vide de taille TAILLE_MAX
  
      
      while(fgets(chaine, TAILLE_MAX, fichier)!= NULL)  // On lit maximum TAILLE_MAX caractères du fichier, on stocke le tout dans "chaine"
      {  
         // On peut lire et écrire dans le fichier
         printf("Le fichier IRIS DATA est ouvert \n");
         
          
    /*----------------- Etape 2 : Allocation mémoire--------------------*/
      /* Allocation mémoire d'un tableau de 100 valeurs flottantes */
    double** vect;
    if  ( ( vect =malloc(100*sizeof(**vect) ))== NULL)
    {
     printf("Il n'y a pas assez de mémoire !\n ");
     exit(EXIT_FAILURE); 
    }
    printf("La memoire est allouee! \n");
    //exit(EXIT_SUCCESS);
    
    
    
           // indice
         int i=0;
   for (i=0;i<=149;i++){
  
   printf("vecteur numero %d \n",i);
   printf("----------------------------------------\n");
   
      fscanf(fichier, "%lf ,%lf ,%lf ,%lf", &vect[i][0], &vect[i][1], &vect[i][2], &vect[i][3]);
   printf("Le vecteur de donnees %d est : %f,%f,%f,%f \n",i, vect[i][0], vect[i][1], vect[i][2], vect[i][3]);
         }
         
    }
  }
  else {                                                                                                                        
         // On affiche un message d'erreur si on veut
         printf("Impossible d'ouvrir le fichier iris_data.txt");
      }
  
    return 0;
}

Merci

1 réponse

fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
20 janv. 2016 à 23:22
Bonjour,

Sans connaître la structure du fichier, c'est difficile de t'aider.
Néanmoins, quelques pistes :

int main()
Le bon prototype est int main(void)

double** vect;
L'allocation n'est pas complète. Tu as alloué le nombre de lignes, mais pas le nombre de colonnes. Il faut faire une boucle for pour allouer de 4 cases chacune des lignes allouées.

exit(EXIT_FAILURE);
Utilise plutôt return EXIT_FAILURE;

for (i=0;i<=149;i++){
Tu fais une allocation de 100 lignes et là, tu itères sur 150 lignes...

fscanf(fichier, "%lf ,%lf ,%lf ,%lf", ...)
Tu as fait un fgets() dans ton while et là, tu refais un fscanf()... Autrement dit, tu lis une ligne pour rien... Utilise plutôt sscanf(chaine, "%lf..."...) pour parser la chaîne sauvegardée plutôt que de lire une ligne de plus dans le fichier.

Attention à l'indentation qui est hasardeuse. Ce n'est pas pratique pour nous de lire...

Cdlt,
0
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017
21 janv. 2016 à 00:34
Merci pour ta réponse!
J'ai corrigé int main(void), et j'ai remplacé le fscanf par sscanf
Par contre, je ce comprends pas cette partie :
double** vect; 
L'allocation n'est pas complète. Tu as alloué le nombre de lignes, mais pas le nombre de colonnes. Il faut faire une boucle for pour allouer de 4 cases chacune des lignes allouées.


Mon fichier est sous cette forme :
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
5.0,3.6,1.4,0.2,Iris-setosa
5.4,3.9,1.7,0.4,Iris-setosa
4.6,3.4,1.4,0.3,Iris-setosa
5.0,3.4,1.5,0.2,Iris-setosa
...........

Il contient 150 lignes et 5 colonnes dont 4 doubles
Comment allouer des lignes et des colonnes ?
Merci
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
Modifié par fiddy le 21/01/2016 à 22:34
double** vect;
Tu veux faire un tableau 150 lignes et 4 colonnes.
Premièrement, on alloue les lignes :
vect=malloc(150*sizeof(*vect));

Note : tu remarqueras que c'est sizeof(*vect) et non sizeof(**vect). Tu alloues une zone de 150 pointeurs.
Ensuite, on alloue les colonnes :
for(i=0; i<4; i++) {
     vect[i]=malloc(4*sizeof(**vect));
}

Note : chacun de ses pointeurs pointeront vers une zone de 4 double...

Je te laisse faire la vérification du code retour des malloc().

Avant la fin de ton programmes, il faudra libérer les zones allouées via des free()... Pareil, boucle for pour faire un free des lignes. Puis un free globale.

Je te conseille vraiment de lire un tuto, car c'est la base.
0
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017
22 janv. 2016 à 18:49
Merci beaucoup fiddy !!
0
geekat Messages postés 228 Date d'inscription vendredi 31 juillet 2015 Statut Membre Dernière intervention 24 février 2017
Modifié par geekat le 22/01/2016 à 18:57
Ça marche!!
J'ai une autre question : comment est-ce que je peux faire des opérations sur les valeurs allouées soient par exemple :
le 1er vecteur : 5.1,3.5,1.4,0.2
Je veux faire un carré de toutes ces valeurs soit :
Carré (5.1*5.1)
Carré (3.5*3.5) .....
Je fais ceci mais ça ne marche pas bien :
J'ai repris le code avec l'allocation mémoire qui marche bien.
La partie <-------------------------CARRE----------------------------> ne marche pas bien.


/* Fichiers d'en-tête */
#include <stdlib.h> // allocation dynamique mémoire
#include <stdio.h> // Gestion erreurs et E/S
#include <math.h> // Fonctions mathématiques
#include <string.h>
#define TAILLE_MAX 4700
// 1ère étape : Chargement du fichier IRIS DATA ==> pas OK
int main()
{ /* Descripteur fichier */
FILE* fichier = NULL;
/* Ouverture fichier */
fichier = fopen("iris_data.txt", "r+");
if (fichier != NULL)
{
char chaine[TAILLE_MAX] = ""; // Chaîne vide de taille TAILLE_MAX
double **vect;
int i,b=1,j;
// On peut lire et écrire dans le fichier
printf("Le fichier IRIS DATA est ouvert \n");
if ((vect = malloc(150*sizeof(double*)))==NULL)
{
printf("Erreur espace");
b=0;
}
for(i=0;i<150;i++)
{
if ((vect[i] = malloc(5*sizeof(double)))==NULL)
{
printf("Erreur espace");
b=0;
}
}
if (b==1)
{
printf("Espace alloue \n");

}
i=0;
while(fgets(chaine, TAILLE_MAX, fichier)!= NULL) // On lit maximum TAILLE_MAX caractères du fichier, on stocke le tout dans "chaine"
{

/*----------------- Etape 2 : Allocation mémoire--------------------*/
/* Allocation mémoire d'un tableau de 100 valeurs flottantes */
if (b==1)
{
sscanf(chaine, "%lf ,%lf ,%lf ,%lf", &vect[i][0], &vect[i][1], &vect[i][2], &vect[i][3]);
printf("Le vecteur de donnees %d est : %f,%f,%f,%f \n",i, vect[i][0], vect[i][1], vect[i][2], vect[i][3]);
double resultat1= (vect[i][0]*vect[i][0]);
printf("\n\n");
printf("-------------------CARRE---------------------\n");
printf("Les resultats sont : %f \n", resultat1);
}
i++;
}
fclose(fichier);

}
else
{
// On affiche un message d'erreur si on veut
printf("Impossible d'ouvrir le fichier iris_data.txt");
}
return 0;
}
0
fiddy Messages postés 11069 Date d'inscription samedi 5 mai 2007 Statut Contributeur Dernière intervention 23 avril 2022 1 835
23 janv. 2016 à 00:12
Bonjour,

Pourquoi utiliser math.h ? Inutile ici.
Pourquoi déclarer la variable j ? Inutile ici.

Pourquoi dis-tu que ça ne marche pas ? Qu'est-ce qui ne fonctionne pas ? Ta syntaxe est correcte.
0