Svp j'ai un problème dans la lecture d'un fichier à travers une fonction readFile.cpp
#include"/home/hamza/SRC/Projet/SRC/declarKmean.hpp"
void readFile(float **x, int &n,int &p, int &c){
FILE* f=NULL;
char nomExt[40];
cout << "Nom du fichier à analyser: ";
cin >> nomExt;
f = fopen(nomExt,"rt");
fscanf(f,"%d",&n); fscanf(f,"%d",&p);
fscanf(f,"%d",&c);
x = new float*[n];
for(int i=0; i<n; i++) x[i] = new float[p+1];
for(int i=0; i<n; i++) for(int j=0; j<p; j++)
fscanf(f,"%f",&x[i][j]);
fclose(f);
}
La fonction main est comme ceci:
#include"/home/hamza/SRC/Projet/SRC/declarKmean.hpp"
int main(){
int n = 0;
int p = 0;
int c = 0;
float **x;
double **v, **oldv;
unsigned int t, tmax;
double eps=0.000001;
v = new double *[c];
for(int i=0; i<c; i++) v[i] = new double[p];
cout << "Donnez le nombre maximal d'itération désirée : \n";
cin >> tmax;
char nomExt[40];
cout << "Nom du fichier à analyser: ";
cin >> nomExt;
readFile(x, &n, &p, &c);
v = new double *[c];
for(int i=0; i<c; i++) v[i] = new double[p];
initMeans(x, v, n, p, c); // voici ma fonction.
do{ t++;
ppp(x, v, n, p, c);
oldv = new double *[c];
for(int i=0; i<c; i++) {oldv[i] = new double[p];}
for(int i=0; i<c; i++) {for(int j = 0; j < p; j++){ oldv[i][j]=v[i][j];}}
newMeans(x, v, n, p, c);
} while( (deltav(v,oldv,c,p) > eps) && (t<tmax) );
writeFile(x, oldv, n, p, c);
return 0;
}
sa declaration
// Déclaration des bibliothèques et des fonctions réutilisables.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
using namespace std;
void initMeans(float **, double **, int , int , int );
double dist(float *, double *, int );
void ppp(float**, double **, int , int, int );
void newMeans(float **, double **, int , int , int );
double deltav(double **, double **, int , int );
void readFile(float **, int *,int *, int *);
void writeFile(float **, double **, int , int , int );
Et le message d erreur sous Ubuntu :
/tmp/ccABJd2d.o: In function `main': main.cpp:(.text+0xe8): undefined reference to `readFile(float**, int*, int*, int*)' collect2: ld returned 1 exit status
Ce code n'est ni du C++, ni du C. C'est un mélange atrocement ignoble des deux. Du coup, il est illisible, pourri de fuites de mémoires, certainement bourré d'accès illégaux.
Je me suis pas trop abimé la rétine, j'ai pas lu le source, mais comme d'hab, le PO n'a pas ajouter le fichier readFile.cpp dans la liste des fichiers sources du projet, donc erreur de link.
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Le deuxieme est dans l ouverture du fichier d entree, il me rend ce message d erreur:
#include"/home/hamza/SRC/Projet/SRC/declarKmean.hpp"
int main(){
int n = 0;
int p = 0;
int c = 0;
float **x=NULL;
double **v=NULL;
double **oldv=NULL;
FILE* f=NULL;
int t = 0;
int tmax = 0;
double eps=0.000001;
v= new double *[c];
for(int i=0; i<c; i++) v[i] = new double[p];
cout << "Donnez le nombre maximal d'itération désirée : \n";
cin >> tmax;
char nomExt[40];
cout << "Nom du fichier à analyser: ";
cin >> nomExt;
f = fopen(nomExt,"r");
fscanf(f,"%d",&n); fscanf(f,"%d",&p);
fscanf(f,"%d",&c);
x = new float*[n];
for(int i=0; i<n; i++) x[i] = new float[p+1];
for(int i=0; i<n; i++) for(int j=0; j<p; j++)
fscanf(f,"%f",&x[i][j]);
fclose(f);
Msg d erreur :
(gdb) run Starting program: /home/hamza/SRC/Projet/SRC/exe warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000 Donnez le nombre maximal d'itération désirée : 9 Nom du fichier à analyser: f.txt
Program received signal SIGSEGV, Segmentation fault. 0x0000000000400c49 in dist (x=0x6042a0, v=0x0, p=2) at dist.cpp:4 4 double ecart = x[i]-v[i]; (gdb) q A debugging session is active.
Le fait de programmer "salement" ne veut pas dire qu'il est impossible que le programme fasse à peu près ce qu'on lui demande, mais il est certain que cela demandera plus de temps, qu'il y a de bonne chance qu'il ne fasse pas ce qu'on pense logiquement qu'il devrait faire, et que la moindre modification/extension prendre un temps fou.
En C++ moderne, un pointeur nu (les machins avec des * en fin du nom des types) c'est quasiment impossible à utiliser correctement (because les exceptions). En C, il n'y a pas d'exception (enfin pas d'exception correctement traitée, because SEH), il est donc envisageable de sans servir, mais pas en C++.
Donc, si vous faites du C++, virez tous ces pointeurs nus de MERDE.
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Je comprends pas ce que vous voulez dire par pointeur nus.
Les pointeurs à base de int*, float*, etc ... sont ce qu'on appelle communément des pointeurs nus. C'est à dire qu'ils permettent l'accès à des ressources mais n'embarquent aucune logique de contrôle de ces ressources. Leur utilité se résume à :
l'implémentation de types permettant le contrôle de ressources de manière intelligente (j'y reviendrai),
l'accès à des ressources distantes de manière non-responsable dans le cas où la non présence de la ressource est acceptable.
Cela induit deux choses :
1. c'est un type de variable complexe à gérer et pas à la portée d'un débutant. Typiquement ici, tu ne prends absolument pas en compte que tes multiples appels à new sont (formellement) susceptibles de lever des exceptions, et donc que tu as besoin d'une politique fiable pour gérer ce genre de cas.
2. quand on a le choix (et ici on a carrément le choix), on utilisera un type permettant de ne pas gérer nous même cette complexité alors que ce n'est pas nécessaire (et c'est bien plus simple !). Ces types sont présents nativement dans la bibliothèque standard du C++ :
Et bien d'autres. On pourra aussi citer (notamment) les pointeurs intelligents.
Ici, ton utilisation se résume à :
des tableaux, pour ça en C++, on utilise std::vector,
des chaînes de caractère, pour ça en C++, on utilise std::string,
des fichiers, pour ça en C++, on utilise std::ifstream/std::ofstream.
Et avec ça tu n'as plus besoin du moindre pointeur dans ton code.
imsanl a écrit:
mon collegue a reussi a executer ce code malgre qu il y a un melange entre le c et le c++.
Ton code actuellement, c'est du C++ tel qu'on le codait en 1980. Il y a eu pas mal de travail entre temps pour en faire un langage (beaucoup) plus sûr, (beaucoup) plus utilisable, (beaucoup) plus pratique, etc ... Par ailleurs, ce n'est pas parce qu'un code s'exécute sur une machine qu'il fonctionne. Il est "tombé en marche", dirons certains d'entre nous ( ). C et C++ ne sont pas du tout les mêmes langages et il est très difficile de les manipuler de manière sure dans un même programme si l'on n'est pas un programmeur un peu chevronné dans les deux langages.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
using namespace std;
int main(){
int n = 0;
int p = 0;
int c = 0;
float **x;
double **v;
FILE* f;
int t = 0;
int tmax = 0;
double eps=0.000001;
v = (double** ) malloc (c * sizeof (double));
for (int i=0;i<c;i++)
{
v[i]=(double*) malloc(p * sizeof(double));
}
printf("Donnez le nombre maximal d'itération désirée : \n");
scanf("%d",&tmax);
char nomExt[40];
printf("Nom du fichier à analyser: ");
scanf("%s",nomExt);
f = fopen(nomExt,"r+");
fscanf(f,"%d",&n); fscanf(f,"%d",&p);
fscanf(f,"%d",&c);
x = (float** ) malloc (n * sizeof (float));
for (int i=0;i < n;i++)
{
x[i]=(float*) malloc((p+1) * sizeof(float));
}
for(int i=0; i<n; i++) for(int j=0; j<p; j++)
fscanf(f,"%f",&x[i][j]);
srand(time(0)); for(int i=0; i<n; i++) x[i][p] = rand()%c;
for(int i = 0; i<n; i++)
for(int j = 0; j<p+1; j++){
if(j!=p) printf("%f \t",x[i][j]);
else printf("%f \n",x[i][j]);
}
double a=0;
for(int i = 0; i < c; i++) for(int j = 0; j < p; j++) {
double num = 0; int denum = 0;
for(int k = 0; k < n; k++) if(x[k][p] == i) {
num += x[k][j]; denum++;
}
v[i][j] = num/denum;
}
for(int i=0; i<c; i++) for(int j = 0; j < p; j++)
printf("%f \t",v[i][j]);
fclose(f);
return 0;
Pourtant, j ai ce message d erreur :
Starting program: /home/hamza/SRC/Projet/SRC/prog warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000 Donnez le nombre maximal d'itération désirée : 9 Nom du fichier à analyser: f.txt 1.000000 1.000000 0.000000 2.000000 1.000000 1.000000 4.000000 3.000000 1.000000 5.000000 4.000000 0.000000
Program received signal SIGSEGV, Segmentation fault. 0x0000000000400c65 in main () at prog.cpp:49 49 v[i][j] = num/denum;
1- using ligne 5 -> si ça compile, c'est que tu utilises un compilateur C++, c'est donc encore du C++ (tout pourri) => change de compilateur !
2- si c'est du C, c'est pas le bon forum
3- même en C, utilises un débuggeur.
P.S.: c'est des accès mémoire foireux, qui n'ont pas lieu d'être en utilisant les outils standards du C++, mais comme tu fais pas de C++, t'as pas de chance.
Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
Si tu veux un code qui compile sans flag avec le compilateur GCC :
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
int main(){
int n = 0;
int p = 0;
int c = 0;
float **x;
double **v;
FILE* f;
int t = 0;
int tmax = 0;
double eps=0.000001;
v = (double** ) malloc (c * sizeof (double));
int i = 0;
int j = 0;
for (i=0;i<c;i++)
{
v[i]=(double*) malloc(p * sizeof(double));
}
printf("Donnez le nombre maximal d'itération désirée : \n");
scanf("%d",&tmax);
char nomExt[40];
printf("Nom du fichier à analyser: ");
scanf("%s",nomExt);
f = fopen(nomExt,"r+");
fscanf(f,"%d",&n); fscanf(f,"%d",&p);
fscanf(f,"%d",&c);
x = (float** ) malloc (n * sizeof (float));
for (i=0;i < n;i++)
{
x[i]=(float*) malloc((p+1) * sizeof(float));
}
for(i=0; i<n; i++) for(j=0; j<p; j++)
fscanf(f,"%f",&x[i][j]);
srand(time(0)); for(i=0; i<n; i++) x[i][p] = rand()%c;
j = 0;
for(i = 0; i<n; i++)
for(j = 0; j<p+1; j++){
if(j!=p) printf("%f \t",x[i][j]);
else printf("%f \n",x[i][j]);
}
double a=0;
int k = 0;
for(i = 0; i < c; i++) for(j = 0; j < p; j++) {
double num = 0; int denum = 0;
for(k = 0; k < n; k++) if(x[k][p] == i) {
num += x[k][j]; denum++;
}
v[i][j] = num/denum;
}
for( i=0; i<c; i++) for(j = 0; j < p; j++)
printf("%f \t",v[i][j]);
fclose(f);
return 0;
}
Mais je ne pense pas que cela fonctionne c'est vraiment codé en mode criminelle ce truc ... Si tu nous disait explicitement ce que dois faire ton programme ? Car c'est vraiment pas claire
Merci beaucoup pour votre aide. Le probleme est resolu. Je vais l implementer sous c et apres sous c++. Vos remarques etaient precieuses et tres utiles pour mon groupe.
Enfin, J'ai réussi à faire fonctionner le programme. Mais le problème se pose quand je définis les variables globales dans le fichier header, le compilateur me rend ce msg ' multiple definition of ':
Voici le fichier Header:
// Fichier en-têtes de Déclaration des bibliothèques, des variables globales et des fonctions réutilisables.
// Date de création: 10/11/2014.
// Auteur: le groupe entier.
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
using namespace std;
int n, p, c; // n: nombre des objets. p: dimension des objtes. c: nombre de classe.
float **x; // vecteur contenant les objets et leurs classifications.
double **v, **oldv; // vecteurs contenant les prototypes.
unsigned int t, tmax; // t: compteur d'itération. tmax: nombre macimal d'itération.
double eps = 0.000001; // Limite de l'écart maximal entre deux prototypes successives.
FILE* f = NULL;// pointeur sur un fichier.
void initMeans(float **, double **, int , int , int );// fonction permettant l'initialisation des prototypes à partir d'une classification aléatoire.
double dist(float *, double *, int);// fonction calculant le carrée de la distance entre un objet et un prototype.
void ppp(float **, double **, int , int, int ); // fonction faisant la classifiction des points aux classes correspondantes.
void newMeans(float **, double **, int , int , int ); // fonction calculant les nouveaux prototypes.
double deltav(double **, double **, int , int ); // fonction calculant l'écart maximum des composants de deux protoypes successives.
void writeFile(float **, double **, int , int , int ); // fonction écrivant dans un fichier les différentes classes et leurs objets associés.
void writeFilegnu(float **, double **, int , int , int );// Fonction écrivant pourque le logiciel gnuplot les dessines.
Voici les fonction reutilisables:
#include"/home/hamza/Bureau/SRC/declarKmean.hpp"
/* fonction permettant l'initialisation des prototypes à partir d'une classification aléatoire */
// Date de création: le 10/11/2014.
// Auteur: Prof A. Bouroumi
void initMeans(float **x, double **v, int n, int p, int c)
{ srand(time(0));
for(int i=0; i<n; i++) x[i][p] = rand()%c;
for(int i = 0; i < c; i++) for(int j = 0; j < p; j++)
{
double num = 0; int denum = 0;
for(int k = 0; k < n; k++) if(x[k][p] == i)
{
num += x[k][j]; denum++;
}
v[i][j] = num/denum;
}
}
/* Fonction qui calcule le carrée de la distance euclidienne entre un point et un prototype */
// Date de création: le 10/11/2014.
// Auteur: Prof A. Bouroumi
double dist(float *x, double *v, int p)
{
double tmp = 0 ;
for(int i = 0; i < p; i++)
{
double ecart = x[i]-v[i];
tmp+= ecart * ecart;
}
return tmp;
}
/* Fonction de classification des objets, comparant le carrée de la distances des objets avec les différents prototypes */
// Date de création: le 13/11/2014.
// Auteur: Prof A. Bouroumi
// Source d'inspiration: Livre "Programmation en C (Exercices résolus)" de Wafaa SABBAR.
void ppp (float **x, double **v, int n, int p, int c){
int min;
for(int i = 0; i < n; i++){ min = 0;
for(int j = 0; j < c; j++){ if( dist (x[i], v[min], p) > dist (x[i], v[j], p) ){ min = j;}}
x[i][p] = min;
}
}
/* Fonction calculant les nouveaux prototypes à partir de la dernière classification des objets */
// Date de création: le 10/11/2014.
// Auteur: Prof A. Bouroumi
void newMeans(float **x, double **v, int n, int p, int c){
for(int i = 0; i < c; i++) for(int j = 0; j < p; j++) {
double num = 0; int denum = 0;
for(int k = 0; k < n; k++) if(x[k][p] == i) {
num += x[k][j]; denum++;
}
v[i][j] = num/denum;
}
}
/* Fonction calculant en valeur absolue le plus grand écart entre les composants de l'ancien et le nouveau ptotype */
// Date de création: le 10/11/2014.
// Auteur: Prof A. Bouroumi
double deltav(double **v, double **oldv, int c, int p){
double deltamax = 0;
for(int i = 0; i < c; i++) for(int j = 0; j < p; j++) {
double ecart = fabs(v[i][j] - oldv[i][j]);
if(deltamax < ecart) deltamax = ecart;
}
return deltamax;
}
/* Fonction qui écrit dans un fichier de sortie les données réparties à leurs classes correspondantes */
// Date de création: le 17/11/2014.
// Auteur: le groupe entier.
void writeFile(float **x, double **v, int n, int p, int c){
FILE* f = NULL;
int flag = 0; // Cet indice aide à écrire les objets de même classe séparée par un point virgule. C0 = {(,);(,)}
char nomExt[40];
cout << "Nom du fichier pour stocker les données dans un fichier: ";
cin >> nomExt;
f = fopen(nomExt,"w");
for(int j = 0; j < c;j++){
flag = 0;
fprintf(f,"la classe %d = {",j);
for(int i = 0; i < n; i++) { if(x[i][p] == j){ if(flag==1) fprintf(f,";");//flag = 1 signifie
//qu'un nombre est déjà écrit dans sa classe associée, ce qui implique l'ajout d'un ;
fprintf(f,"(");
for(int k = 0; k < p; k++) { if(k!=p-1) fprintf(f,"%f,",x[i][k]);
else fprintf(f,"%f)",x[i][k]); flag =1;// drapeau indique
//s il existe au moins un point.
}
}
}
fprintf(f,"}. \t Le centre de la classe %d = (",j);
for(int k = 0; k < p; k++){ if(k!= p-1) fprintf(f,"%f, ",v[j][k]);
else fprintf(f,"%f).",v[j][k]);
}
fprintf(f,"\n");
}
fclose(f);
}
/* Fonction écrivant dans un fichier de sortie les objets classifiées, pourque le logiciel gnuplot les dessine */
// Date de création: 19/11/2014
// Auteur: groupe entier.
void writeFilegnu(float **x, double **v, int n, int p, int c)
{
FILE* f=NULL;
char nomExt[40];
cout << "Nom du fichier du gnuplot: ";
cin >> nomExt;
f = fopen(nomExt,"w");
for(int i = 0; i<n; i++) for(int j = 0; j<p+1; j++){
if(j!=p) {fprintf(f,"%f",x[i][j]);
fprintf(f," ");}
else {fprintf(f,"%f",x[i][j]);
fprintf(f,"\n");}
}
}
Voici la fonction main()
#include"/home/hamza/Bureau/SRC/declarKmean.hpp"
/* Module principal de l'algorithme K-means */
// Ce fichier est crée le 18/11/2014.
// Auteur: le groupe entier.
int main(){
/* Lecture des données depuis un fichier d'entrée choisi par l'utilisateur */
cout << "Donnez le nombre maximal d'itération désirée : \n";
cin >> tmax;
char nomExt[40];
cout << "Nom du fichier à analyser: ";
cin >> nomExt;
f = fopen(nomExt,"rt");
fscanf(f,"%d",&n); fscanf(f,"%d",&p);
fscanf(f,"%d",&c);
x = new float*[n];
for(int i=0; i<n; i++) x[i] = new float[p+1];
for(int i=0; i<n; i++) for(int j=0; j<p; j++) fscanf(f,"%f",&x[i][j]);
fclose(f);
/* Fonction initMeans */
v = new double *[c];
for(int i=0; i<c; i++) v[i] = new double[p];
/* L'appel des fonctions réutilisables */
initMeans(x,v,n,p,c);
do{ t++;
ppp(x, v, n, p, c); // Classification des objets.
oldv = new double *[c];// la copie de v dans oldv.
for(int i=0; i<c; i++) oldv[i] = new double[p];
for(int i=0; i<c; i++) for(int j = 0; j < p; j++) oldv[i][j]=v[i][j];
newMeans(x, v, n, p, c);// Calcul des nouveaux prototypes.
} while((deltav(v,oldv,c,p) > eps) && (t<tmax) );
writeFile(x, oldv, n, p, c);//Ecriture dans le fichier de sortie.
return 0;
}
J'ai bien compris ce que vous avez dit avant, mais j ai pas le temps de refaire les choses. Ce code marche bien (malgré qu'il est sale). Le seul problème que j'ai c'est déclarer les variables dans le fichier header. Si vous pouvez nous donnez un exemple de code qui illustre soit extern soit #ifndef DECLARKMEAN_H_INCLUDED #define DECLARKMEAN_H_INCLUDED, car j ai pas compris comment utiliser extern.
Merci infiniment les gars, j'ai appris beaucoup de choses avec vous. Dans le prochain projet j'essaie d'appliquer tous les remarques que vous avez cité.
Cordialement.
Lecture d'un fichier
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Objectif Zéro Bug - le test logiciel professionnel | L'électronique de zéro | Tableaux & pointeurs | Pointeurs sur fonctions | Lecture/écriture binaire
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C