Lecture de fichiers (commence bien mais le programme s'arrete)

vercd7am Messages postés 34 Date d'inscription samedi 17 juillet 2010 Statut Membre Dernière intervention 14 mai 2012 - 13 oct. 2010 à 23:35
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 14 oct. 2010 à 13:42
Bonjour, j'ai un probleme avec le programme suivant; je veux lire deux fichiers, l'un contient une colonne de nombres, l'autre des coordonnees: je lis autant de coordonnees que le nombre marque dans le premier fichier, par groupes de trois nombres. Mon programme commence bien, lit bien, mais finit toujours par me renvoyer le message que mon programme a arrete de fonctionner et je ne comprends pas pourquoi.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "structure.h"

int main()
{
     char nom1[]="C:\\FichierNombre.txt";
    // fichiers contenant le nombre de points a l'interieur de la fenetre erodee
    char nom2[]="C:\\FichierCoordonnees.txt";
    // fichiers contenant les coordonnees des points

    float R=0;

    int C1, C2;

  FILE* fichier = NULL;

  fichier = fopen(nom1,"r");

  if(fichier != NULL)
  {

      FILE* fichier2 = NULL;

      fichier2 = fopen(nom2,"r");

      if(fichier2!= NULL)
      {
          int N1, N2, N3;
    for(C1=1; C1<2; C1++)
    {
     fscanf(fichier, "%d %d %d", &N1, &N2, &N3);  //N1 nombre dans la fenetre erodee, N2 ceux aux bords de la fenetre erodee et a l interieur, N3 ceux a l exterieur
     printf("%d %d %d \n\n", N1, N2, N3);           // N1 + N3 = nombre total de points dans le processus

     struct coordonnees* points1; // je cree un pointeur sur ma structure processus pour les points dans la fenetre erodee
     points1 = (struct coordonnees*)malloc(N1* sizeof(*points1));
     struct coordonnees* points2; // je cree un pointeur sur ma structure processus pour les points au bord
     points2 = (struct coordonnees*)malloc(N2* sizeof(*points2));
     struct coordonnees* points3; // je cree un pointeur sur ma structure processus pour les points a l exterieur
     points3 = (struct coordonnees*)malloc(N3* sizeof(*points3));

     int u,v,w;
// partie correspondant a la fenetre erodee
        for(u=0;u<N1+1;u++)
        {
            fscanf(fichier2,"%lf %lf", &points1[u].x, &points1[u].y);
            printf("x: %f, y:%f\n", points1[u].x, points1[u].y);
        }
// partie correspondant au bord de la fenetre erodee
        for(v=0;v<N2+1;v++)
        {
            fscanf(fichier2,"%lf %lf", &points2[v].x, &points2[v].y);
            printf("x: %f, y:%f\n", points2[v].x, points2[v].y);
        }
// partie correspondant a l exterieur de la fenetre erodee
        for(w=0;w<N3+1;w++)
        {
            fscanf(fichier2,"%lf %lf", &points3[w].x, &points3[w].y);
            printf("x: %f, y:%f\n", points3[w].x, points3[w].y);
        }
    }
    }
    else{printf("big problem2");}
    fclose(fichier2);
  }
  else
  {
      printf("big problem\n");
  }
  fclose(fichier);

  return 0;
}



le fichier structure.h est le suivant (super basique)
struct coordonnees
{
    double x;
    double y;
};


R et C2 ne servent pour l'instant a rien mais c'est normal
C1 ne prend que la valeur 1 car c'est juste un test

Pour voir, j'ai essaye de mettre en commentaire ma boucle for pour N2, et celle pour N3, defois il fonctionne sans probleme, defois il fonctionne mais me renvoie egalement le message d'arret, idem quand je met la boucle for avec N3 en commentaire et que je remplace N2 par un nombre(toujours plus petit que la valeur de N2 sinon il y aurait un probleme vu la taille de points2), defois ca passe, defois ca renvoie l'erreur.

La je cale, je ne comprends vraiment pas pourquoi. Quelqu'un pourrait-il m'aider? Merci d'avance.

7 réponses

cs_louis14 Messages postés 793 Date d'inscription mardi 8 juillet 2003 Statut Membre Dernière intervention 10 février 2021 8
14 oct. 2010 à 09:52
Bonjour,
Est-ce que tu peux lancer ton programme en mode debug. Et dans ce cas tu suis pas pas ton programme et tu verras ce qui ne va pas.
tu peux aussi ajouter le nombre d'éléments retournés far fscanf afin de vérifir si les données sont bien lues : int ret = fscan... et tu affiches cette valeur aussi.
Bon debuguage.


louis
0
vercd7am Messages postés 34 Date d'inscription samedi 17 juillet 2010 Statut Membre Dernière intervention 14 mai 2012
14 oct. 2010 à 10:24
ben justement, le debug dis que tout va bien
Building to ensure sources are up-to-date
Build succeeded
Selecting target:
Debug
Adding source dir: C:\Users\alicek\Desktop\Didier\NP\
Adding source dir: C:\Users\alicek\Desktop\Didier\NP\
Adding file: bin\Debug\NP.exe
Starting debugger:
done
Registered new type: wxString
Registered new type: STL String
Registered new type: STL Vector
Setting breakpoints
Debugger name and version: GNU gdb 6.8
Child process PID: 5156
Program exited normally.
Debugger finished with status 0
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
14 oct. 2010 à 10:44
Le "+ 1" que tu mets dans tes boucles fait que tu dépasses la taille de tes tableaux :)

Petites remarques:
- Utilise un compilateur C, et pas un compilo C++ si tu fais du C ! Ça se voit (je parie que tu utilises Dev-C++). En C, il est inutile de caster le retour du malloc, par exemple.
- Découpe ton code en petite fonction. Diviser un gros problème difficile en plein de petits problèmes faciles, est la clé du succès.
- louis14 à fait une remarque judicieuse: tester le retour de fscanf (je ne le fais pas dans mon exemple ci-dessous, mais il faudrait).
- Ne pas oublier de libérer les ressources allouées, via free().

J'ai appliqué ce que je t'ai dit sur ton code:
#include <stdio.h>
#include <stdlib.h>

struct coordonnees
{
  double x;
  double y;
};

void getSize(const char* filename, int* size1, int* size2, int* size3)
{
  FILE* file = fopen(filename,"r");
  if (file == NULL)
  {
    printf("big problem\n");
    return;
  }

  /* Plus besoin de & devant size1, size2 et size3, car ce sont des pointeurs, le "&" a déjà été précisé avant */
  fscanf(file, "%d %d %d", size1, size2, size3);
  fclose(file);
}

struct coordonnees* readCoords(FILE* file, int size)
{
  int i = 0;
  struct coordonnees* points;
  points = malloc(size * sizeof(struct coordonnees));
  for(i = 0; i < size; ++i)
  {
    fscanf(file,"%lf %lf", &points[i].x, &points[i].y);
    printf("x: %f, y:%f\n", points[i].x, points[i].y);
  }

  return points;
}

void readAllCoords(const char* filename, int size1, int size2, int size3)
{
  FILE* file = fopen(filename,"r");
  struct coordonnees* points1;
  struct coordonnees* points2;
  struct coordonnees* points3;

  if (file == NULL)
  {
    printf("big problem 2\n");
    return;
  }

  points1 = readCoords(file, size1);
  points2 = readCoords(file, size2);
  points3 = readCoords(file, size3);

  free(points1);
  free(points2);
  free(points3);

  fclose(file);
}

int main()
{
  int C1;
  int n1, n2, n3;

  getSize("FichierNombre.txt", &n1, &n2, &n3);
  printf("Taille: %d %d %d \n\n", n1, n2, n3);
  for(C1 = 1; C1 < 2; ++C1)
    readAllCoords("FichierCoordonnees.txt", n1, n2, n3);

  return 0;
}


________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
14 oct. 2010 à 10:51
D'ailleurs, en petit exercices, je te propose d'améliorer ce que j'ai fait.
Dans la fonction readCoord, j'ai fait un truc pas terrible: je n'ai pas séparé la lecture et l'affichage.
Fait donc une fonction "displayCoords" qui se charge d'afficher le contenu d'un tableau de coord, et appelle là dans "readAllCoords". Tu pourras ensuite retirer l'affichage dans readCoord, qui n'a rien à faire là.

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
vercd7am Messages postés 34 Date d'inscription samedi 17 juillet 2010 Statut Membre Dernière intervention 14 mai 2012
14 oct. 2010 à 12:00
Merci, le +1 etait visiblement bien le probleme, entre temps je m'etais rendu compte que j'avais oublie le free. Merci aussi pour le code supplementaire.

J'utilise code blocks en mode console mais bien pour du C, mais je suis debutant, pointer n'est pas encore super evident et les fonction qui vont avec de meme.

J'aurais encore aime savoir quelquechose. Si j'ai reecris le programme, c'est parce qu'au depart j'utilisais non pas deux fichiers mais beaucoup plus, 100*177=17 700 que j'ecrivais avec un autre programme. Je l'ai reecris pour mettre tous les fichiers les uns a la suite des autres. Est-ce que cette nouvelle solution est plus rapide, beaucoup plus rapide, ou bien que cela ne change rien?

Par ailleurs, la suite du programme continue sur du calcul de distance entre les points dont les coordonnees sont dans les fichiers. Au total j'ai toujours environ 1000 points par configuration, 100 configurations, et je dois calculer le nombre de triplets a,b,c plus proche qu'une certaine longueur (d(a,b)<r, d(a,c)<r, d(b,c)<r pour r variant de 0 a 0,24 par 0,01). C'est super demandant pour le processeur, j'en gagne un peu en mettant un certain nombre de if pour n'avoir a calculer que le minimum de distances entre points, mais ca reste enorme (1000^3 c'est gros). Est-ce que pour ce type de calcul, je peux gagner enormement en temps avec un code en assembleur?
0
vercd7am Messages postés 34 Date d'inscription samedi 17 juillet 2010 Statut Membre Dernière intervention 14 mai 2012
14 oct. 2010 à 12:01
Je vais tenter l'exercice, sans doute ce soir. J'espere me montrer a la hauteur.
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
14 oct. 2010 à 13:42
J'utilise code blocks en mode console mais bien pour du C, mais je suis debutant, pointer n'est pas encore super evident et les fonction qui vont avec de meme.

Code::Block a un compilateur de C++, il me semble (je me demande si on ne peut pas lui spécifier dans les options d'utiliser un compilateur C).

Est-ce que cette nouvelle solution est plus rapide, beaucoup plus rapide, ou bien que cela ne change rien?

La solution présentée est juste une réécriture un peu plus élégante, elle ne change strictement rien en terme de performance. En revanche, je pense qu'elle est plus lisible et donc plus maintenable. D'une manière générale, une fonction ne devrait pas dépasser une trentaine de ligne.

Si j'ai reecris le programme, c'est parce qu'au depart j'utilisais non pas deux fichiers mais beaucoup plus, 100*177=17 700 que j'ecrivais avec un autre programme. Je l'ai reecris pour mettre tous les fichiers les uns a la suite des autres.

Là, y a peut être un problème de conception. Comment peux-tu avoir 17 700 fichiers à lire ? Si je peux avoir le contexte, je peux peut être te donner une meilleur approche. Parce qu'ouvrir et fermer 17 700 fois des fichiers, ça coute cher !

Par ailleurs, la suite du programme continue sur du calcul de distance entre les points dont les coordonnees sont dans les fichiers. Au total j'ai toujours environ 1000 points par configuration, 100 configurations, et je dois calculer le nombre de triplets a,b,c plus proche qu'une certaine longueur (d(a,b)<r, d(a,c)<r, d(b,c)<r pour r variant de 0 a 0,24 par 0,01). C'est super demandant pour le processeur, j'en gagne un peu en mettant un certain nombre de if pour n'avoir a calculer que le minimum de distances entre points, mais ca reste enorme (1000^3 c'est gros). Est-ce que pour ce type de calcul, je peux gagner enormement en temps avec un code en assembleur?

Passer en assembleur ne te fera pas forcément gagner en perf, surtout si ton assembleur n'est pas terrible.
La meilleur chose à faire est de faire un algorithme performant, et de voir si ton code C est correctement optimisé. Jouer avec les options du compilateur peut pas mal aidé aussi.

Si tu dois lire souvent des fichiers, je te conseille de les mapper en mémoire, via mmap (sous Unix) et via GetMapViewOfFile (ça doit être à peu près le nom sous Windows).
L'utilisation d'outils de calcul de performance aide aussi beaucoup à détecter les points de ralentissements (callgrind sous Unix, et sous Windows, ben, heu... Je ne sais pas, mais ça doit exister :p).

________________________________________________________________________
Historique de mes créations, et quelques articles:
[ http://0217021.free.fr/portfolio http://0217021.free.fr/portfolio]
Merci d'utiliser Réponse acceptée si un post répond à votre question
0
Rejoignez-nous