IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Comment utiliser fread pour remplire 1tableau dynamique


Sujet :

C

  1. #1
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 17
    Points : 13
    Points
    13
    Par défaut Comment utiliser fread pour remplire 1tableau dynamique
    Bonjour

    je m'y connais pas trop dans l'allocation dynamique, mais j'en ai besoin pour allouer une grande taille de données.

    j'ai une image Tiff de grande taille, je veux la charger dans une matrice dynamique ( vu qu'avec la statique les grande tailles c'est pas possible)
    enfin bref je veux utiliser fread successivement afin de lire la premiere ligne (12000 premiers bytes ou 6000 Word) ensuite je la réutilise pour la deuxieme ligne et ainsi de suite.
    je sais que ca se fait mais je sais pas le aire, et en plus je ne sais pas si fread prend en compte les matrices, ou elle charge uniquement dans des vecteurs?


    pour le moment mon programme ressemble a ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    //Déclaration
    const T=6000;     
     
    Word** ptr=new Word*[T];    //j'utilise Word car les données sont codées sur 16bits
    for(int i=0;i<T;i++)        //allocation dynamique de ptr le pointeur que je vais utiliser dans fread
        ptr[T] = new Word[T];
     
    Word ** Matrice=new Word*[T];
    for(int i=0;i<T;i++)        //allocation dynamique de la matrice qui va contenir l'image
        Matrice[T] = new Word[T];
     
    //Routine d'ouverture 
    if(OpenDialog1->Execute())
      {
     
       FILE *fichier1 = fopen (Form2->OpenDialog1->FileName.c_str(), "rb") ;
       if (!fichier1){
            ShowMessage ("Impossible d'ouvrir le fichier\n" +Form2->OpenDialog1->FileName);
            return ;
            }
     
      fread (ptr,T, T, fichier1); // là  je me demande si  il va me charger 6000 ligne et 6000 colonne dans la matrice ptr 
     
     
      for (int j=0; j<T; j++)
      for (int i=0; i<T; i++)
          {
     
           Matrice[i][j]= ptr[i][j];
           if  (Matrice[i][j] > 255) Matrice[i][j]=255; //Seuillage à la valeur maximale
           if  (Matrice[i][j] < 0) Matrice[i][j]=0;     //Seuillage à la valeur minimale
     
           Form2->Image1->Canvas->Pixels[i][j]=         //Affichage de l'image 
           TColor (RGB(Matrice[i][j],Matrice[i][j],Matrice[i][j]));
          }
       }
    mais à l'exécution sur la ligne Matrice[i][j]= ptr[i][j]; il me fait une erreur : "le projet a provoqué une classe d'exception avec le message débordement de pile"

    alors correction please et merci d'avance pour votre aide

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Tout d'abord, ce code n'est pas du C. Quant à fread, cette fonction lit des données depuis un fichier pour les placer dans un buffer c'est-à-dire un espace continu alloué. Ta matrice n'utilise pas une mémoire continue parce qu'elle est issue de plusieurs allocations dynamiques. Tu dois appeller fread pour chaque ligne de ta matrice c'est-à-dire faire une lecture ligne par ligne.

  3. #3
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 17
    Points : 13
    Points
    13
    Par défaut
    ah désolé je me suis trompé de rubrique, je suis nouveau excusez moi ( vous pouvez transférer le sujet a la rubrique C++ )

  4. #4
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 17
    Points : 13
    Points
    13
    Par défaut
    Quant à fread, cette fonction lit des données depuis un fichier pour les placer dans un buffer c'est-à-dire un espace continu alloué. Ta matrice n'utilise pas une mémoire continue parce qu'elle est issue de plusieurs allocations dynamiques. Tu dois appeller fread pour chaque ligne de ta matrice c'est-à-dire faire une lecture ligne par ligne.
    donc si j'ai bien compris ca doit etre ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //déclaration
    Word ptr[6000]; 
     
    // utilisation de fread
     
    for (int j=1; j<T; j++)
    {
     fread (ptr,T, 1, fichier1);
     for (int i=0; i<T; i++)
          {
           Matrice [i][j]=ptr[i];
          }
    }
    et comme ça a chaque fread il va lire le "bloc" suivant de 6000 Word?


    je viens d'essayer j'ai encore une classe d'exception avec violation d'acces dans la ligne Matrice [i][j]=ptr[i];
    comment faire donc pour manipuler cet espace dans le buffer?

  5. #5
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Déjà, je l'avais pas remarqué ce matin, il y a une erreur dans ton allocation. Le code doit être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Word ** p = malloc(NLIGNES * sizeof(Word*));
    for(i = 0; i < NLIGNES; i++)
        p[i] = malloc(NCOLONNES * sizeof(Word));
    Ou avec new si tu veux le faire en C++. Et j'ai pas mis les tests d'erreurs (qui sont obligatoires).

    Pour la lecture ligne par ligne t'as bien vu, je l'adapte dans ton cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(i = 0; i < NLIGNES; i++)
        fread(ptr[i], sizeof(Word), NCOLONNES, f_in);
    Mais ça :
    Citation Envoyé par MClover
    Je ne comprends pas comment as-tu pu écrire une chose pareille. Correction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(j = 0; j < NCOLONNES; j++)
        Matrice[i][j] = ptr[i][j];
    Sinon tu as aussi memset qui fait déjà ça. Et au fait, je ne comprends pas vraiment pourquoi tu utilises deux matrices (ptr et Matrice) mais bon, c'est ton code.

  6. #6
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 17
    Points : 13
    Points
    13
    Par défaut
    Merci Melem pour les indications
    Maintenant je maitrise mieux les allocations dynamiques, mais cette fois je préfère charger les données sur un vecteur au lieu d’une matrice, et a chaque lecture de ligne je l’affiche puis je l’écrase avec la suivante.
    la deuxième matrice c’était pour la sauvegarde, mais je n’ai pas encore trouvé la fonction qui sauvegarde une matrice dans un fichier !!

    Voila le programme corrigé


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    const T=12000 ;            //résolution de l’image  
    int temp;
    Word * ptr;
    ptr= new  Word [T];
     
    Word ** Matrice;
    Matrice = new  Word*[T];
    for (int i=0; i<T; i++)
     Matrice [i]=new Word[T];
     
     
    if(OpenDialog1->Execute())
      {
     
      FILE *fichier1 = fopen (Form2->OpenDialog1->FileName.c_str(), "rb") ;
      if (!fichier1) {
                        ShowMessage ("Impossible d'ouvrir le fichier\n" +Form2->OpenDialog1->FileName);
                        return ;
                        }
     
      for (int j=0; j<(T/2); j++)
           {
            fread (ptr,2, T, fichier1);
     
            for (int i=0; i<(T/2); i++)
                 {
                 Matrice[i][j]= ptr[i];
                 temp = (ptr[i]*255)/1000;  // car les valeurs que j’ai sont des altitudes donc les plus grandes seront les plus claires (règle de trois)
                 if (temp>255)temp=255; // seuillage pour les altitudes dépassant 1000
                 Form2->Image1->Canvas->Pixels[i][j]=TColor(RGB(temp,temp,temp));
      }
          }
      }

  7. #7
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Si T désigne bien la "résolution" de l'image (qui en fait n'est pas la résolution mais la définition) et si l'image est bien carrée avec 8 bits de profondeur (8 bits / pixel) comme le laisse penser ton code (qui est alors inexact), tu devrais mettre Racine(T) à la place de tes T/2. Or à ma connaissance 12000 n'est pas un carré ... (louche). De même l'allocation doit être revisitée. En tous cas, quelque soit la réalité, ton code me semble faux. Ne sachant pas trop ce que tu veux exactement faire, je ne peux pas trop t'aider sur la conception par contre je te conseille de spécifier séparemment le nombre de lignes et de colonnes de ton image (même s'ils ont la même valeur). Ton code sera ainsi plus lisible.
    je n’ai pas encore trouvé la fonction qui sauvegarde une matrice dans un fichier !!
    fwrite permet d'écrire le contenu d'un tableau dans un fichier. Pour une matrice allouée dynamiquement, on prpcède toujours ligne par ligne.

  8. #8
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 17
    Points : 13
    Points
    13
    Par défaut
    Non Melem, la valeur de chaque pixel (altitude) est codée sur 16bits, et c’est pour ca que j’utilise le Word et non pas le Byte. (j’ai découvert le word dans le menu d’aide de mon compilateur,
    Il est vrai que ca a l’air ambigüe mon code, et pas très lisible.
    En fait pour le T/2 j’y ai eu recours car l’image s’affichait rayée avec des lignes horizontales, donc pour resserrer les lignes j’ai réduit leur nombre.
    Mais tout ca c’était a cause du fait que je chargeais le double de ce qu’il fallait dans ptr (12000 word au lieu de 6000).
    En suivant ton conseil je vais non seulement séparer le nombre de lignes et de colonnes affichés mais encore je vais séparer la taille de ptr, de telle sorte qu’elle soit toujours égale a 6000, puisque pour commencer à lire les données de la deuxième ligne on est obligé de charger d’abord la 1ere (les 6000 pixels).

    Et comme ça je pourrai choisir la taille de la "fenêtre" à afficher (pouvoir afficher just une partie de l’image)

    Voila ce que devient mon code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    const DefR=6000;       //Définition réelle de l'image 
    const NLin=300;         //nombre de lignes a afficher
    const NCol=500;        //nombre de colonnes a afficher
    int temp;
     
    Word * ptr;            //la structure ou l'on va charger l'image ligne par ligne
    ptr= new  Word [DefR];
     
    if(OpenDialog1->Execute())
    {
     
      FILE *fichier1 = fopen (Form2->OpenDialog1->FileName.c_str(), "rb") ;
    if (!fichier1){
            ShowMessage ("Impossible d'ouvrir le fichier\n" +Form2->OpenDialog1->FileName);
            return ;
                      }
     
    fread (ptr,2, 4, fichier1);    // dépasser l'entete (8bytes=4Word)
     
     
    for (int j=0; j<(NLin); j++)
     {
     fread (ptr,2, DefR, fichier1);         /*à chaque fois on va charger 6000 donnée*/
     
    for (int i=0; i<(NCol); i++)          //colonnes
        {
         temp = (ptr[i]*255)/1000;    // car les valeurs que j’ai sont des altitudes donc les plus grandes seront les plus claires 
         if (temp>255)temp=255; // seuillage pour les altitudes dépassant 1000
                 Form2->Image1->Canvas->Pixels[i][j]=TColor(RGB(temp,temp,temp));
          }
      }

  9. #9
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par MClover
    Non Melem, la valeur de chaque pixel (altitude) est codée sur 16bits, et c’est pour ca que j’utilise le Word et non pas le Byte.
    Ouais bien sûr. J'ai vu 255 traîner quelque part c'est pour ça que j'ai dit ça sans réfléchir ...

    Sinon, je ne sais pas comment tu fais tes calculs mais si l'image est bien constituée de 300 lignes et 500 colonnes, la définition de l'image est de 300 * 500 pixels = 150 000 pixels. Et si le nombre de bytes par pixel est 2 (word), alors la taille de l'image est de 300 000 bytes.

    Lorsque tu mets 2 et que ce 2 fait référence à la taille d'un Word, écris plutôt sizeof(Word) (lisibilité ...).

    Puisqu'une ligne est constituée de 500 pixels (500 words ou encore 1000 bytes), lire une ligne revient à lire 500 words (1000 bytes).

  10. #10
    Membre à l'essai
    Inscrit en
    Avril 2008
    Messages
    17
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 17
    Points : 13
    Points
    13
    Par défaut
    Sinon, je ne sais pas comment tu fais tes calculs mais si l'image est bien constituée de 300 lignes et 500 colonnes, la définition de l'image est de 300 * 500 pixels = 150 000 pixels. Et si le nombre de bytes par pixel est 2 (word), alors la taille de l'image est de 300 000 bytes.

    Puisqu'une ligne est constituée de 500 pixels (500 words ou encore 1000 bytes), lire une ligne revient à lire 500 words (1000 bytes).
    En fait l'image physique contient 6000Ligne*6000Colonne
    les 300*500 que je j'ai choisi c'est just une partie de l'image réelle, c'etais just un exemple, je travaille comme ça pour mieux connaitre mes données et metriser la methode que j'utilise pour les manipuler.

    avec ce mini programme lu but c'etait d'apprendre a utiliser fread successivement pour lire les données de mon image.

    En tout cas merci bcp a toi pour les conseils et ton aide

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [TPW] Comment utiliser tdw pour tpw 1.5 ?
    Par Grebarne dans le forum Turbo Pascal
    Réponses: 1
    Dernier message: 20/12/2006, 15h03
  2. comment utiliser Scanner pour parser un String?
    Par ricardvince dans le forum Langage
    Réponses: 4
    Dernier message: 03/10/2006, 14h15
  3. Réponses: 4
    Dernier message: 18/05/2006, 09h20
  4. comment utiliser Notepad pour modifier un fichier texte?
    Par moon13_698 dans le forum Autres Logiciels
    Réponses: 7
    Dernier message: 06/05/2006, 15h41
  5. Réponses: 2
    Dernier message: 27/04/2006, 16h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo