[C++] prog lecture et récup de data

Résolu/Fermé
cherquaoui - 1 avril 2007 à 20:33
 cherquaoui - 6 avril 2007 à 19:16
bonjour,
je serais vraiment très content si vous pouviez m'aidez.
j'ai un programme en C++ a faire et comme c'est ma premiere, j'ai un peu du mal.
en fait j'ai un projet a faire et j'ai besoin d'un code lecture de fichier et récuperation de données.
je vous mets un exemple de fichier :

0: (1,0) (2,0) (3,5580) (4,5002) (5,5028) (6,3778)
1: (0,0) (2,0) (3,2828) (4,5249) (5,5361) (6,5373) (7,5052) (8,4171)
2: (0,0) (1,0) (3,5847) (4,4771) (5,5451)

3: (4,0) (5,0) (0,5580) (1,2828) (2, 5847)
4: (3,0) (5,0) (0,5002) (1,5249) (2,4771)
5: (3,0) (4,0) (0,5028) (1,5361) (2,5451)

6: (7,0) (8,0) (0,3778) (1,5373)
7: (6,0) (8,0) (1,5052)
8: (6,0) (7,0) (1,4171)

en fait c'est une matrice !

Chaque ligne d'un fichier correspond à une ligne de la matrice et se
présente sous la forme :
<n°ligne>:\tab(<n°colonne>,<coefficient>)\tab(<n°colonne>,<coefficient>)\tab(<n°colonne>,<coefficient>)\tab(<n°colonne>,<coefficient>)\tab(<n°colonne>,<coefficient>)...

donc pour pouvoir faire des calculs , il faut que je récupere toutes les données de cette matrice.
et je ne sais vraiment pas comment faire en C++.

si vous pouvez m'aidez , ca m'aiderai beaucoup et ca me permettrai de gagner un temps fou.
merci.
A voir également:

16 réponses

mamiemando Messages postés 33636 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2025 7 842
2 avril 2007 à 00:58
Très sincèrement on a vu des façons de stocker les données un peu plus simples. Matrices pleines :
M00 M01 M02 M03 ...
M10 M11 M12 M13 ...
M20 M21 M22 M23 ...
... ... ... ... ...

Matrice creuses :
ligne colonne valeur

Mais bon on va dire que ça fait partie de l'exercice d'avoir un fichier chiant à lire ^^ Le mieux c'est de décomposer ta fonction de lecture ainsi : l'idée :
lire_fichier :
  pour chaque ligne
    lire_ligne(ligne)

lire_ligne :
  lire no_ligne
  tant qu'il reste des "maillons"
    lire no_colonne et valeur du maillon courant
    lire le reste de la ligne

#include <fstream>
#include <iostream>
#include <string>
#include <map>

// une matrice creuse d'entiers
typedef std::map<unsigned,std::map<unsigned,int> > matrix_t;

extern "C"{
  #include <stdio.h> // sscanf
  #include <stdlib.h> // malloc, free
}

bool lire_ligne(const std::string & line,matrix_t & matrix){
  const char *str = line.c_str();
  char *buffer =(char *) malloc(sizeof(char)*(line.size()+1));
  unsigned ligne,colonne;
  int valeur;
  bool continuer;
  if(sscanf(buffer," %i : %s",&ligne,&buffer)!=2){
    return false;
  }
  std::cout << "numero de ligne : " << ligne << " : " ;
  do{
    int res=sscanf(buffer,"( %i , %d ) %s",&colonne,&valeur,&buffer);
    if (res == 0) break; 
    if (res == 1) return false; // maillon incomplet ou invalide (on ignore
    continuer = (res == 3); // le buffer contient
    matrix[ligne][colonne] = valeur;
  }while(continuer)
  free(buffer);
  return true;
}

bool lire_fichier(const char *filename,matrix_t & matrix){
  std::ifstream f(filename);
  if (f){
    std::cout << "Lecture de [" << filename << ']' << std::endl;
    std::string line;
    for(unsigned noline=1;std::getline(f,ligne);++noline){
      if(!lire_ligne(line,matrix){
        std::cerr << "Erreur : ligne invalide : ligne " << noline << ": " 
        << line << std::endl;
        return false; // on arrête la lecture
      }
    }
    return true; // lecture ok
  }
  std::cerr << "Ne peut ouvrir [" << filename << ']' << std::endl;
  return false; // le fichier n'existe pas ou ne peut être ouvert
}

int main(){
  const char *filename = "plop.txt";
  matrix_t m;

  // Lire le fichier
  if(!lire_fichier(filename,m)){
    std::cerr << "Le contenu du fichier [" << filename << "] est invalide " << std::endl;
    return 1;
  }
  
  // Afficher la matrice
  {
    std::map<unsigned,std::map<unsigned,int> >::const_iterator
      mit1(m.begin()),mend1(m.end());
    for(;mit1!=mend1;++mit1){
      const unsigned & ligne = mit1->first;
      const std::map<unsigned,int> & ligne_matrice = mit1->second;
      std::map<unsigned,int>::const_iterator
        mit2(ligne_matrice.begin()),mend2(ligne_matrice.end());
      for(;mit2!=mend2;++mit2){
        const unsigned & colonne = mit2->first;
        const int & valeur = mit2->second;
        std::cout <<'(' << ligne << ',' << colonne << ") = " << valeur << std::endl;
      }
    }
  }
  return 0;
}

Ou un truc dans le genre... là je fais ça en live je n'ai pas de compilateur sous la main
0
mercii beaucoup de ton aide précieuse!
c clair que c chiant d'avoir un telle stockage de matrix mé j'y peu rien , les fichiers sont enregistrés comme ca, et je dois faire avec.
par contre j'ai kelke petite kestion.
j'ai bien compris le prinicpe, d'ailleurs je savais qu'il fallait proceder ligne par ligne mais je ne savais pas comment travailler sur chaque ligne.
maintenat grace a vous et avec la fonction map dont je ne connaissais meme pas l'existence j'ai compris!

encore un pti problème de compilation:
j'ai tout compilé j'ai enlevé d petites erreurs de syntaxe, mais il en reste que je ne comprend pas.
le compilateur "icc" me renvoi :
main.cpp(53): warning #181: argument is incompatible with corresponding format string conversion
if(sscanf(buffer," %i : %s",&ligne,&buffer)!=2){
^

main.cpp(58): warning #181: argument is incompatible with corresponding format string conversion
int res=sscanf(buffer,"( %i , %d ) %s",&colonne,&valeur,&buffer);
^

main.cpp(65): error: expected a ";"
free(buffer);
^

compilation aborted for main.cpp (code 2)


je pense qu'il doit avoir un probleme avec le " while (continuer) free ..."

mais je ne sais pas ce que c! de plus il ya kelke warning mais c pas genant.


je vous remerci beaucoup de votre aide , et de la rapidité avec laquelle vous m'aviez répondu.
très bien ce forum!! rien a dire!

j'attend votre réponse avec impatience! merci
0
une petite question sur le résultat après la lecture :
la matrice m dans le main est déclaré avec troix tableau c ca?

donc pour ke je puisse travailler avec c donnée il suffit d'ecrire "m[..][..]; "
c bien ca?
merci encore une fois
0
c bon j'ai trouvé l'ereur de syntaxe, en fait cté tt bete, javais pas vu kil manquait la virgule!
mé en mm temps a 4h du matiin, jsui moins lucide!!
maintenant il me reste juste a savoir si le prog marche é commen les données sont elles stocké dan lé var déclaré!
0
re,
c dommage! on y etait preque!
il y a une erreur sur la premiere ligne!enfin c ckil affche!

bon voila mon code , jle teste sur le fichier du haut , j'ai fait d ptite modif sur le programme aprè erreur du compilateur, jje vous montr lé correction que j'ai faite et puis le resultat affiché aprè exécution!


#include <fstream>
#include <iostream>
#include <string>
#include <map>

// une matrice creuse d'entiers
typedef std::map<unsigned,std::map<unsigned,int> > matrix_t;

extern "C"{
#include <stdio.h> // sscanf
#include <stdlib.h> // malloc, free
}

bool lire_ligne(const std::string & line,matrix_t & matrix){
    const char *str = line.c_str();
    char *buffer =(char *) malloc(sizeof(char)*(line.size()+1));
    unsigned ligne,colonne;
    int valeur;
    bool continuer;
    if(sscanf(buffer," %i : %s",&ligne,buffer)!=2){                                           //G ENLEVE LE & DEVANT BUFFER
	return false;
    }
    std::cout << "numero de ligne : " << ligne << " : " ;
    do{
	int res=sscanf(buffer,"( %i , %d ) %s",&colonne,&valeur,buffer);                                                                      //LA AUSSI G ENLEVE LE &
	if (res == 0) break;
	if (res == 1) return false; // maillon incomplet ou invalide (on ignore
	continuer = (res == 3); // le buffer contient
	matrix[ligne][colonne] = valeur;
    }
    while(continuer) ; 
// G MI LA VIRGULE      
	free(buffer);
    
       return true;

}

bool lire_fichier(const char *filename,matrix_t & matrix){
    std::ifstream f(filename);
    if (f){
	std::cout << "Lecture de [" << filename << ']' << std::endl;
	std::string line;
	for(unsigned noline=0;std::getline(f,line);++noline){                         // G COMMENCE LE COMPTEUR A 0 O LIEU DE 1 ET G CHANGE "ligne " par "line" ( erreur de syntaxe). 
	    if(!lire_ligne(line,matrix)){
		std::cerr << "Erreur : ligne invalide : ligne " << noline << ": "
			  << line << std::endl;
		return false; // on arrête la lecture
	    }
	       }
	    return true; // lecture ok
	}
	std::cerr << "Ne peut ouvrir [" << filename << ']' << std::endl;
	return false; // le fichier n'existe pas ou ne peut être ouvert
    }



    int main(){
	const char *filename = "test.dat";
	matrix_t m;
	
// Lire le fichier
	if(!lire_fichier(filename,m)){
	    std::cerr << "Le contenu du fichier [" << filename << "] est invalide " << std::endl;
	    return 1;
	}
	
// Afficher la matrice
	{
	    std::map<unsigned,std::map<unsigned,int> >::const_iterator
		mit1(m.begin()),mend1(m.end());
	    for(;mit1!=mend1;++mit1){
		const unsigned & ligne = mit1->first;
		const std::map<unsigned,int> & ligne_matrice = mit1->second;
		std::map<unsigned,int>::const_iterator
		    mit2(ligne_matrice.begin()),mend2(ligne_matrice.end());
		for(;mit2!=mend2;++mit2){
		    const unsigned & colonne = mit2->first;
		    const int & valeur = mit2->second;
		    std::cout <<'(' << ligne << ',' << colonne << ") = " << valeur << std::endl;
		}
	    }
	}
	return 0;
    }




donc voila , en fait g pa vraimen fé bocou de changement ( 4 en tt expliké en com dan le code) conséken sur le résultat ki est :


Lecture de [test.dat]
Erreur : ligne invalide : ligne 0: 0: (1,0) (2,0) (3,5580) (4,5002) (5,5028) (6,3778)
Le contenu du fichier [test.dat] est invalide



j'attendrai votre réponse pour pouvoir avancer mon projet ! merci bocou!
0
mamiemando Messages postés 33636 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2025 7 842 > cherquaoui
2 avril 2007 à 09:10
main.cpp(53): warning #181: argument is incompatible with corresponding format string conversion
if(sscanf(buffer," %i : %s",&ligne,&buffer)!=2){
^


if(sscanf(buffer," %i : %s",&ligne,buffer)!=2){


main.cpp(58): warning #181: argument is incompatible with corresponding format string conversion
int res=sscanf(buffer,"( %i , %d ) %s",&colonne,&valeur,&buffer);
^


int res=sscanf(buffer,"( %i , %d ) %s",&colonne,&valeur,buffer);


main.cpp(65): error: expected a ";"
free(buffer);
^


Rajouter entre le while(...) et le free
0
mamiemando Messages postés 33636 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2025 7 842
3 avril 2007 à 00:20
Ecris en français s'il te plaît j'ai trop de mal à lire là.
Dans la fonction lire_fichier il suffit d'afficher la ligne courante pour voir où il en est :
std::cout << line << std::endl;

Procède de même avec les maillons et tu vas vite voir où il bloque.

Bonne chance
0
désolé pour l'écriture mais c'est le stress qui me rend comme ca!

en fait je crois que l'erreur venait de la boucle if de la premiere fonction, je l'ai modifié comme ceci :

bool lire_ligne(const std::string & line,matrix_t & matrix){
      const char *str = line.c_str();
     char *buffer =(char *) malloc(sizeof(char)*(line.size()+1));
//char buffer[1024];
    unsigned ligne,colonne;
    int valeur;
    bool continuer;
    // std::  cout<<"jsui laaaa";
    if(sscanf(buffer," %i : %s",&ligne,buffer)!=2){ 
	std::cout << "numero de ligne : " << ligne << " : " ;
    do{
	int res=sscanf(buffer,"( %i , %d ) %s",&colonne,&valeur,buffer);
//	cout<< "num colonne"<<colonne;
//	cout<<"coef"<< valeur ;
//	cout <<"buffer"<<buffer;
	if (res == 0) break;
	if (res == 1) return false; // maillon incomplet ou invalide (on ignore
	continuer = (res ==3 ); // le buffer contient
	matrix[ligne][colonne] = valeur;

    }
     while(continuer) ;
	free(buffer);
    
       return true;
    }
    else {
      
	return false;
    }
    


de plus dans l'affichage de la matrice j'ai rajouté ca a la fin mais le résultat est faux!


/ Afficher la matrice
	{
	    std::map<unsigned,std::map<unsigned,int> >::const_iterator
		mit1(m.begin()),mend1(m.end());
	    for(;mit1!=mend1;++mit1){
		const unsigned & ligne = mit1->first;
		const std::map<unsigned,int> & ligne_matrice = mit1->second;
		std::map<unsigned,int>::const_iterator
		    mit2(ligne_matrice.begin()),mend2(ligne_matrice.end());
		for(;mit2!=mend2;++mit2){
		    const unsigned & colonne = mit2->first;
		    const int & valeur = mit2->second;
		    std::cout <<'(' << ligne << ',' << colonne << ") = " << valeur << std::endl;
		}
	    }
	}	std::cout<<"une valeur de la matrice    " <<m[1][3]<<std::endl;
	return 0;
    }


resulat de l'exécution :

Lecture de [test.txt]
numero de ligne : 10 : numero de ligne : 10 : numero de ligne : 10 : numero de ligne : 10 : numero de ligne : 10 : numero de ligne : 10 : numero de ligne : 10 : numero de ligne : 10 : numero de ligne : 10 : numero de ligne : 10 : numero de ligne : 10 : (10,0) = 0
une valeur de la matrice 0


c'est toujours 10 le numéro de la ligne ???
de plus la valeur n'est pas correcte, je ne vois vraiment pas ou est le pb!
merci mamiemado.
0
voila, j'ai eu ma dose pour aujourd'hui!
je vais aller me coucher, si vous pouviez vraiment m'aidez a le debuguer , ca m'aiderai énormément!
merci mamiemando pour ton aide précieuse!

alors pour l'instant, j'ai trouvé une erreur dans le :

" int res = sscanf(....) "

en fait res est toujours = -1 !!


bool lire_ligne(const std::string & line,matrix_t & matrix){
const char *str = line.c_str();
char *buffer =(char *) malloc(sizeof(char)*(line.size()+1));
unsigned ligne,colonne;
int valeur;
bool continuer;
if(sscanf(buffer," %i : %s ",&ligne,buffer)!=2){
std::cout << "numero de ligne : " << ligne << " : " ;
do{
int res=sscanf(buffer,"( %i , %d ) %s",&colonne,&valeur,buffer);

std::cout<<colonne<<" "; // AFFICHAGE
std::cout<<"res = "<<res<<std::endl;

if (res == 0) break;
if (res == 1) return false; // maillon incomplet ou invalide (on ignore
continuer = (res ==3 ); // le buffer contient
matrix[ligne][colonne] = valeur;
}
while(continuer) ;


free(buffer);

return true;
}


else
{
return false;
}

}
0

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

Posez votre question
(dsl pti souci clavier)msg 15 ( celui davant )a ne pas prendre en compte!


voila, j'ai eu ma dose pour aujourd'hui!
je vais aller me coucher, si vous pouviez vraiment m'aidez a le debuguer , ca m'aiderai énormément!
merci mamiemando pour ton aide précieuse!

alors pour l'instant, j'ai trouvé une erreur dans le :

" int res = sscanf(....) "

en fait res est toujours = -1 !!
bool lire_ligne(const std::string & line,matrix_t & matrix){ 
const char *str = line.c_str(); 
char *buffer =(char *) malloc(sizeof(char)*(line.size()+1)); 
unsigned ligne,colonne; 
int valeur; 
bool continuer; 
if(sscanf(buffer," %i : %s ",&ligne,buffer)!=2){ 
std::cout << "numero de ligne : " << ligne << " : " ; 
do{ 
int res=sscanf(buffer,"( %i , %d ) %s",&colonne,&valeur,buffer); 

std::cout<<colonne<<" "; // AFFICHAGE 
std::cout<<"res = "<<res<<std::endl; 

if (res == 0) break; 
if (res == 1) return false; // maillon incomplet ou invalide (on ignore 
continuer = (res ==3 ); // le buffer contient 
matrix[ligne][colonne] = valeur; 
} 
while(continuer) ; 


free(buffer); 

return true; 
} 


else 
{ 
return false; 
} 

}


donc ici j'ai rajouté deux affichage ou je constate une erreur pour la ligne, car elle est toujours egale a 10 ! je ne sais vraiment pas pk!
de plus res = -1 donc ya pa de traitement dans la suite de la boucle!

resultat de l'exécution :


Lecture de [test.txt]
numero de ligne : 10 : 0   res  =  -1
numero de ligne : 10 : 0   res  =  -1
numero de ligne : 10 : 0   res  =  -1
numero de ligne : 10 : 0   res  =  -1
numero de ligne : 10 : 0   res  =  -1
numero de ligne : 10 : 0   res  =  -1
numero de ligne : 10 : 0   res  =  -1
numero de ligne : 10 : 0   res  =  -1
numero de ligne : 10 : 0   res  =  -1


je ne sais plus quoi faire! aidez moi SVP!
0
mamiemando Messages postés 33636 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2025 7 842
3 avril 2007 à 10:22
#include <fstream>
#include <iostream>
#include <string>
#include <map>

// une matrice creuse d'entiers
typedef std::map<unsigned,std::map<unsigned,int> > matrix_t;

extern "C"{
#include <stdio.h> // sscanf
#include <string.h>
}

bool lire_ligne(const std::string & line,matrix_t & matrix){
    const char *str = line.c_str();
    char *buffer = (char *)malloc(sizeof(char)*(line.size()+1));
    strcpy(buffer,str);
    unsigned ligne,colonne;
    int valeur;
    bool continuer;
    if(sscanf(buffer," %i : ",&ligne)!=1){
        free(buffer);
        return false;
    }
//  std::cout << "numero de ligne : " << ligne << " : "  << std::endl;
    do{
//      std::cout << "\tbuffer = " << buffer << std::endl;
        int res=sscanf(buffer,"( %i , %d ) %s\n",&colonne,&valeur,buffer);
//      std::cout << '(' << colonne << ',' << valeur << ')' << buffer << '[' << res << ']' << std::endl;
        if (res == 0) break;
        if (res == 1) return false; // maillon incomplet ou invalide (on ignore
        continuer = (res == 3); // le buffer contient
        matrix[ligne][colonne] = valeur;
    }while(continuer);
    free(buffer);
    return true;

}

bool lire_fichier(const char *filename,matrix_t & matrix){
    std::ifstream f(filename);
    if (f){
        std::cout << "Lecture de [" << filename << ']' << std::endl;
        std::string line;
        for(unsigned noline=1;std::getline(f,line);++noline){
            if(line.empty()) continue;
            if(!lire_ligne(line,matrix)){
                std::cerr << "Erreur : ligne invalide : ligne " << noline << ": "
                    << line << std::endl;
                return false; // on arrête la lecture
            }
        }
        return true; // lecture ok
    }
    std::cerr << "Ne peut ouvrir [" << filename << ']' << std::endl;
    return false; // le fichier n'existe pas ou ne peut être ouvert
}

int main(){
    const char *filename = "plop.txt";
    matrix_t m;

    // Lire le fichier
    if(!lire_fichier(filename,m)){
        std::cerr << "Le contenu du fichier [" << filename << "] est invalide " << std::endl;
        return 1;
    }

    // Afficher la matrice
    {
        std::map<unsigned,std::map<unsigned,int> >::const_iterator
            mit1(m.begin()),mend1(m.end());
        for(;mit1!=mend1;++mit1){
            const unsigned & ligne = mit1->first;
            const std::map<unsigned,int> & ligne_matrice = mit1->second;
            std::map<unsigned,int>::const_iterator
                mit2(ligne_matrice.begin()),mend2(ligne_matrice.end());
            for(;mit2!=mend2;++mit2){
                const unsigned & colonne = mit2->first;
                const int & valeur = mit2->second;
                std::cout <<'(' << ligne << ',' << colonne << ") = " << valeur << std::endl;
            }
        }
    }
    return 0;
}

Voilà ou j'en suis. Pour une raison mystérieuse le sscanf ne remplace pas buffer avec le reste de la ligne mais juste le premier maillon, je ne sais pas trop pourquoi... Moi je t'avoue que je parse mes fichiers avec des expressions régulières en lib pcre mais là ça devrait être assez simple pour le faire avec des sscanf out des istringstream. Mais je n'ai pas le temps de regarder dans le détail comment ça marche. Je t'invite à éplucher les tutoriels pour parser un fichier en C++.

Bonne chance
0
svp, si il ya quelqu'un qui pourrait m'aider a debuguer ce programme, parce que franchement je galère en C++ avec 30h de cours et TP dans ma formation ce ne m'aide pas vraiment!
je vous en supplie j'en ai vraiment besoin de ce programme!

mamiemando m'a beaucoup, je le remercie énormément, cependant il n'a pas beaucoup de temps pour pouvoir se concentrer dans les détails.
il m'a proposé d'aller voir les tutos pour parser un fichier, mais j'y comprend pas grand chose.

Alors s'il vous plait aidez moi, j'ai un grand projet et ce programme m'est important pour avancer! merci.

si il n'y a personne! j'espère que tu pourra trouver un petit temps libre pour jetter un petit coup d'oeil au debuguage du programme mamiemando!
merci.
cordialement.
0
au fait mamimando, si tu peut faire comme tu avais l'habitude de parser les fichiers ie (en lib pcre) et que ca marche , alors je suis prenant de toute proposition !
merci beaucoup.
0
mamiemando Messages postés 33636 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2025 7 842
4 avril 2007 à 01:59
Bon je capte pas pourquoi le sscanf se comporte comme ca, mais je crois que j'ai trouvé la fonction qu'il te faut : strtok.
Tu fais une boucle dont les tokens sont les parenthèses, et dans celle ci une autre boucle qui detecte les virgule. Un exemple est donné dans le man
      #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>

       int
       main(int argc, char *argv[])
       {
           char *str1, *str2, *token, *subtoken;
           char *saveptr1, *saveptr2;
           int j;

           if (argc != 4) {
               fprintf(stderr, "Usage: %s string delim subdelim\n",
                       argv[0]);
               exit(EXIT_FAILURE);
           }

           for (j = 1, str1 = argv[1]; ; j++, str1 = NULL) {
               token = strtok_r(str1, argv[2], &saveptr1);
               if (token == NULL)
                   break;
               printf("%d: %s0, j, token);

               for (str2 = token; ; str2 = NULL) {
                   subtoken = strtok_r(str2, argv[3], &saveptr2);
                   if (subtoken == NULL)
                       break;
                   printf(" --> %s0, subtoken);
               }
           }

           exit(EXIT_SUCCESS);
       } /* main */

       Voici un exemple de la sortie produite par ce programme :

       $ ./a.out ’a/bbb///cc;xxx:yyy:’ ’:;’ ’/’
       1: a/bbb///cc
                --> a
                --> bbb
                --> cc
       2: xxx
                --> xxx
       3: yyy
                --> yyy

Ici les séparations des "maillons" se font sur les caractères : et ; (argv[1]), et les données des maillons sur le caractère / (argv[2]). Dans ton cas le séparateurs inetr maillons sont ')(', et le séparateru intra maillon est ','. En adaptant cet exemple tu devrais t'en sortir.

Bon courage
0
merci de me soutenir toujours!
donc je vais essayer ca demain, par contre je voulais savoir si la structure map je la gardait toujours ou pas ?
est ce que je dois complétement supprimer les fonctions lireligne et lire_fichier et adapter cette exemple ou pas!
merci pour ton aide.
0
mamiemando Messages postés 33636 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2025 7 842
4 avril 2007 à 09:52
L'avantage de la map c'est que tu n'as pas besoin de connaître les dimensions de ta matrice au préalable. De plus si la matrice est creuse elle est très rentable en terme de place occupée en mémoire (en gros proportionnelle au nombre de cellules non nulles) et d'accès (O(log(n)log(n)). Une matrice pleine (par exemple un int ** ou un std::vector<std::vector<unsigned> >) sera elle beaucoup plus rapide en accès (O(1)) mais aussi beaucoup plus coûteuse en mémoire (proportionnelle à n.n) et suppose que tu connaisses les dimensions de ta matrice (ou tu devras faire des reallocations, ce qui est assez coûteux en terme de performances si la matrice est grosse). On peut tout à fait imaginer que tu passes dans un premier temps par une structure de matrice creuse, que tu cherches le nombre de ligne et de colonne requis, et que tu convertisses cette structure en matrice pleine. Moi c'est ce que je te conseille.

Tu noteras que pour récupérer des données dans une structure de map tu dois faire des find et pour la parcourir il faut passer par des iterator. Tu peux faire pareil pour une matrice basée sur des vector, mais tu peux aussi directement utiliser l'opérateur []. En particulier si cet opérateur existe pour les map, il ne sert normalement que pour l'insertion de valeurs car il ne garantit pas la constance de la map et ne devrait jamais être utilisé pour autre chose (passer par des find).

Pour la lecture de ton fichier je t'ai parlé de lib pcre mais c'est bien compliqué pour un truc simple. Je t'invite à bosser l'exemple sur les strtok normalement c'est assez simple. Je ne te cache pas que la difficulté réside dans ton format de fichier qui est somme toute assez peu pratique (si je puis me permettre :p). Mais bon il a au moins le mérite de fournir un bon exercice ;)
0
franchement, j'ai compris le principe mais je n'arrive pas a l'adapter au code que tu m'a fourni au début.
c'est vraiment dur pour moi.
en + c chiant ce type de fichier c clair, mais bon jsui en stage dans un centre de recherche connu en france et je travaille sur une partie d'un projet secret dont je pourrai en parler quand je rendrai mon travail.
mais moi ce programme m'est important pour avancer plus vite c'est pour ca jsui venu demander de l'aide.
et j'espere que tu pourai vraiment me sauver. j'ai encore une semaine pour récuperer toutes les données et traviller dessus.
merci mamiemando, et sache que j'ai vraiment besoin de ton aide pour avancer mon projet.
merci.
0
mamiemando Messages postés 33636 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2025 7 842
5 avril 2007 à 14:41
Hey faut insister un peu, parce que sinon moi je veux toucher un pourcentage sur la paye ;)
#include <string.h>
#include <stdio.h>

int main(){
    char test[80];
    char *sep = "()";
    char *word, *brkt;
    int x=0,y=0;

    strcpy(test, "(1,2) (3,4) (5,6)");
    printf ("test = %s\n",test);

    for (word = strtok_r(test, sep, &brkt); word; word = strtok_r(NULL, sep, &brkt)){
        printf("word = [%s] \n", word);
        if(sscanf(word,"%d,%d ",&x,&y) == 2){
            printf("x=%d y=%d\n",x,y);
        }
    }
    return 0;
}

Bonne chance
0
merci encore une fois pour ton aide précieuse.

en ce qui concerne la paye! je touche rien du tt!
on est engagé par notre école, en échange on acquiere de l'expérience. mais comme le projet me passionne, j'aimerai bien apporter quelque chose qui marque un peu ma présence au sein de l'entreprise et les chercheurs.
si jamais je touche quelque chose je ne manquerai pas de t'envoyer un pti pourcentage! :)

sinon par rapport au programme je l'ai modifié de tel sorte mais j'ai pas encore ce qu'il faut.
explication : après que j'ai modifié le code, je récupere juste les dernieres valeurs de chaque ligne! pourtant je parcours bien chaque ligne.
mais je pense que je dois avoir une erreur dans le "do et le while continuer ".
#include <fstream>
#include <iostream>
#include <string>
#include <map>

// une matrice creuse d'entiers
typedef std::map<unsigned,std::map<unsigned,int> > matrix_t;

extern "C"{
#include <stdio.h> // sscanf
#include <string.h>
}

bool lire_ligne(const std::string & line,matrix_t & matrix){
	const char *str = line.c_str();
	char *buffer = (char *)malloc(sizeof(char)*(line.size()+1));
	strcpy(buffer,str);
	unsigned ligne=0;
	unsigned colonne=0;
	int valeur;
	bool continuer;
	char test[800];
	char *sep = "()";
	char *word, *brkt;
	
	 if(sscanf(buffer," %i : ",&ligne)!=1){
	      free(buffer);
        return false;
	 }
	 else 
	 {
	      do {
	     
	     //  std::cout << "numero de ligne : " << ligne << " : "  << std::endl;
	     
		 strcpy(test,buffer);
		 //	 printf ("test = %s\n",test);
		 
		 
		 for (word = strtok_r(test, sep, &brkt); word; word = strtok_r(NULL, sep, &brkt)){
		     // printf("word = [%s] \n", word);
		     int  res = sscanf(word,"%i,%d ",&colonne,&valeur);
		     if(res == 2){
			 //	 printf("colonne=%i valeur=%d\n",colonne,valeur);
			     }
		      continuer = ( res== 3); //le buffer contient
		 }
		 matrix[ligne][colonne] = valeur;
		  }  while(continuer);
	      free(buffer);
	     return true;
	 }
}


bool lire_fichier(const char *filename,matrix_t & matrix){
    std::ifstream f(filename);
    if (f){
        std::cout << "Lecture de [" << filename << ']' << std::endl;
        std::string line;
        for(unsigned noline=1;std::getline(f,line);++noline){
            if(line.empty()) continue;
            if(!lire_ligne(line,matrix)){
                std::cerr << "Erreur : ligne invalide : ligne " << noline << ": "
                    << line << std::endl;
                return false; // on arrê la lecture
            }
        }
        return true; // lecture ok
    }
    std::cerr << "Ne peut ouvrir [" << filename << ']' << std::endl;
    return false; // le fichier n'existe pas ou ne peut êe ouvert
}

int main(){
    const char *filename = "test.txt";
    matrix_t m;

    // Lire le fichier
    if(!lire_fichier(filename,m)){
        std::cerr << "Le contenu du fichier [" << filename << "] est invalide " << std::endl;
        return 1;
    }
	
    // Afficher la matrice
    {
        std::map<unsigned,std::map<unsigned,int> >::const_iterator
            mit1(m.begin()),mend1(m.end());
        for(;mit1!=mend1;++mit1){
            const unsigned & ligne = mit1->first;
            const std::map<unsigned,int> & ligne_matrice = mit1->second;
            std::map<unsigned,int>::const_iterator
                mit2(ligne_matrice.begin()),mend2(ligne_matrice.end());
            for(;mit2!=mend2;++mit2){
                const unsigned & colonne = mit2->first;
                const int & valeur = mit2->second;
                std::cout <<'(' << ligne << ',' << colonne << ") = " << valeur << std::endl;
            }
        }std::cout<< " m[2][3]  =    "<<m[2][3]<< std::endl; 
    }

    return 0;
}


résultat :
Lecture de [test.txt]
(0,6) = 3778
(1,8) = 4171
(2,5) = 5451
(3,2) = 5847
(4,2) = 4771
(5,2) = 5451
(6,1) = 5373
(7,1) = 5052
(8,1) = 4171
 m[2][3]  =    0



stp on é pa trè loin alors j'ai besoin juste d'un peti coup de pouce pour la fin ! merci
0
mamiemando Messages postés 33636 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 18 avril 2025 7 842
5 avril 2007 à 22:44
Je te mets la solution ci dessous
bool lire_ligne(const std::string & line,matrix_t & matrix){
    const char *str = line.c_str();
    char *buffer = (char *)malloc(sizeof(char)*(line.size()+1));
    strcpy(buffer,str);
    unsigned ligne=0;
    unsigned colonne=0;
    int valeur;
    char *sep = "()";
    char *maillon, *brkt;

    if(sscanf(buffer," %i : ",&ligne)!=1){
        free(buffer);
        return false;
    }
    strtok_r(buffer,":", &brkt);
//  std::cout << " :  >> buffer = " << buffer << std::endl;
//  std::cout << " :  >> brkt = " << brkt << std::endl;
    for (maillon = strtok_r(brkt, sep, &brkt); maillon; maillon = strtok_r(NULL, sep, &brkt)){
        printf("maillon = [%s] \n", maillon);
        int res = sscanf(maillon,"%i,%d ",&colonne,&valeur);
        if(res == 2) matrix[ligne][colonne] = valeur;
    }

    free(buffer);
    return true;
}

Ce qui m'embête c'est que d'un point de vue pédagogique ça aurait été mieux que tu touves tout seul. Je t'ai laissé en commentaire les deux lignes qui m'ont permi de voir où était le problème. Il faut que tu prennes ce reflexe (afficher les variables dans les fonctions qui se comportent mal) et une fois que tu auras compris pourquoi leur valeur est mauvaise, tu sauras d'où vient le problème.

En l'occurence dans le strtok_r, le premier paramètre pointe sur la chaîne à analyser, le second spécifie le ou les caractères séparateurs, et le troisième stocke la position du premier séparateur trouvé. Une fois que tu as compris ça, le code source ... coule de source

Bonne chance
0
c clair que d'un point de vue pédagogique j'aurais bien voulu trouver tout seul,mais le temps ne me permettait pas de me concentrer sur les détails, j'étais plus intéréssé par le coeur du sujet.
mais en tt cas merci beaucoup pour tes conseils. et pour ton aide qui m'a permis de bien avancer!
encore merci beaucoup.

je reviendrai pour te donner des retours sur le projet ( qui est d'ailleurs un projet europeen pour la recherche du traffic aerien) .
0