[C++] prog lecture et récup de data
Résolu/Fermé
A voir également:
- [C++] prog lecture et récup de data
- App data - Guide
- Confirmation de lecture whatsapp - Guide
- Accusé de lecture gmail - Guide
- Télécharger livre de lecture ce2 gratuit pdf - Télécharger - Éducatifs
- Lecture epub sur pc - Guide
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
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 :
Matrice creuses :
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 :
Ou un truc dans le genre... là je fais ça en live je n'ai pas de compilateur sous la main
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
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
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 :
Procède de même avec les maillons et tu vas vite voir où il bloque.
Bonne chance
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
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 :
de plus dans l'affichage de la matrice j'ai rajouté ca a la fin mais le résultat est faux!
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.
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.
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;
}
}
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;
}
}
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 !!
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 :
je ne sais plus quoi faire! aidez moi SVP!
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!
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
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
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.
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.
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.
merci beaucoup.
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
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
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
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
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.
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.
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
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 ;)
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 ;)
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.
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.
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
5 avril 2007 à 14:41
Hey faut insister un peu, parce que sinon moi je veux toucher un pourcentage sur la paye ;)
Bonne chance
#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
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 ".
résultat :
stp on é pa trè loin alors j'ai besoin juste d'un peti coup de pouce pour la fin ! merci
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
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
5 avril 2007 à 22:44
Je te mets la solution ci dessous
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
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
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) .
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) .
2 avril 2007 à 03:25
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
2 avril 2007 à 03:31
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
2 avril 2007 à 03:49
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é!
2 avril 2007 à 04:17
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!
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!
2 avril 2007 à 09:10
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);
^
Rajouter entre le while(...) et le free