[C++] lecture de fichier pb d'indice
chreks
-
chreks -
chreks -
bonjour,
j'ai besoin de votre aide s'il vous plait. je suis un débutant en C++ et je galère pour résoudre un problème concernant la récupération de données à partir d'un fichier.
en fait mon fichier est une matrice creuse qui se présente de cette facon :
0: (1,0) (2,0) (3,5) (4,2) (5,8) (6,3) (7,2) (8,4)
1: (0,0) (2,0) (3,8) (4,4) (5,1) (6,7) (7,5) (8,3)
2: (0,0) (1,0) (3,7) (4,4) (5,2) (6,2) (7,3) (8,6)
3: (4,0) (5,0) (0,5) (1,8) (2,7) (6,2) (7,6) (8,8)
4: (3,0) (5,0) (0,2) (1,4) (2,4) (6,3) (7,9) (8,1)
5: (3,0) (4,0) (0,8) (1,1) (2,2) (6,6) (7,7) (8,9)
6: (7,0) (8,0) (0,3) (1,7) (2,2) (3,2) (4,3) (5,6)
7: (6,0) (8,0) (0,2) (1,5) (2,3) (3,6) (4,9) (5,7)
8: (6,0) (7,0) (0,4) (1,3) (2,6) (3,8) (4,1) (5,9)
c'est une matrice dont je récupere les données avec une structure map pour la matrice et donc j'aimerais faire des calculs sur cette 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>)...
mon programme est le suivant et j'ai petit problème d'indice que je n'arrive pas à voir, et qui me bloke tous les calculs qui suivent!
" normalemen c une matrice symetrique"
à l'exécution j'obtient une matrice ou a l'affichage il manque la derniere ligne et la derniere colonne, j'ai trouvé ca bizare, j'ai regardé la valeur de nb_row pr connaitre la nombre de ligne ( = 8 dans ce cas de fichier alors ke ca devrai etre 9 jpense ) , je pense qu'il y une ligne en moins !! a moins que j'ai mal compris le fonctionnement du programme é commen nb_row marchait.
de plus dans les boucles d'affcihage kan je rajoute un" nb_row+1 " je vois afficher les lignes et colonnes manquantes mais je pensais ke cétait incorrecte parckil y a un terme en +!
alors SVP aidez moi c urgen!!
merci d'avance.
j'ai besoin de votre aide s'il vous plait. je suis un débutant en C++ et je galère pour résoudre un problème concernant la récupération de données à partir d'un fichier.
en fait mon fichier est une matrice creuse qui se présente de cette facon :
0: (1,0) (2,0) (3,5) (4,2) (5,8) (6,3) (7,2) (8,4)
1: (0,0) (2,0) (3,8) (4,4) (5,1) (6,7) (7,5) (8,3)
2: (0,0) (1,0) (3,7) (4,4) (5,2) (6,2) (7,3) (8,6)
3: (4,0) (5,0) (0,5) (1,8) (2,7) (6,2) (7,6) (8,8)
4: (3,0) (5,0) (0,2) (1,4) (2,4) (6,3) (7,9) (8,1)
5: (3,0) (4,0) (0,8) (1,1) (2,2) (6,6) (7,7) (8,9)
6: (7,0) (8,0) (0,3) (1,7) (2,2) (3,2) (4,3) (5,6)
7: (6,0) (8,0) (0,2) (1,5) (2,3) (3,6) (4,9) (5,7)
8: (6,0) (7,0) (0,4) (1,3) (2,6) (3,8) (4,1) (5,9)
c'est une matrice dont je récupere les données avec une structure map pour la matrice et donc j'aimerais faire des calculs sur cette 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>)...
mon programme est le suivant et j'ai petit problème d'indice que je n'arrive pas à voir, et qui me bloke tous les calculs qui suivent!
#include <fstream>
#include <iostream>
#include <map>
#include <list>
#include <string>
#include <vector>
#include <stdlib.h>
#include <math.h>
extern "C"{
#include <stdio.h> // sscanf
#include <string.h>
}
template <typename Tkey1,typename Tkey2,typename Tdata>
class sparse_matrix_t : public std::map<Tkey1,std::map<Tkey2,Tdata> >{
public:
typedef std::map<Tkey2,Tdata> row_t;
typedef std::map<Tkey1,row_t> matrix_t;
// Recuperer une valeur
inline Tdata get(const Tkey1 & k1,const Tkey1 & k2) const {
typename matrix_t::const_iterator f1(this->find(k1));
if(f1 == this->end()) return Tdata();
const row_t & r = f1->second;
typename row_t::const_iterator f2(r.find(k2));
if(f2 == r.end()) return Tdata();
return f2->second;
}
};
// Une classe de matrice creuse indexée (les deux clés sont des entiers positifs)
template <typename Tdata>
class indexed_sparse_matrix_t : public sparse_matrix_t<unsigned,unsigned,Tdata>{
protected:
std::size_t nb_row;
std::size_t nb_col;
public:
// Le constructeur
indexed_sparse_matrix_t():
sparse_matrix_t<unsigned,unsigned,Tdata>(),
nb_row(0),nb_col(0)
{}
// Affecter une valeur
inline void set(const unsigned & k1,const unsigned & k2,const Tdata & d){
(*this)[k1][k2] = d;
if(k1 > nb_row) nb_row = k1+1;
if(k2 > nb_col) nb_col = k2+1;
}
// Recuperer le nombre de ligne
inline const std::size_t & get_nb_row() const{
return nb_row;
}
// Recuperer le nombre de colonne
inline const std::size_t & get_nb_col() const{
return nb_col;
}
};
// Afficher la matrice (operateur <<)
template <typename Tstream,typename Tdata>
Tstream & operator<<(Tstream & out,const indexed_sparse_matrix_t<Tdata> & m){
const std::size_t & nb_row = m.get_nb_row();
const std::size_t & nb_col = m.get_nb_col();
for(std::size_t i=0;i<nb_row;++i){
for(std::size_t j=0;j<nb_col;++j) out << m.get(i,j) << '\t';
out << std::endl;
}
return out;
}
bool lire_ligne(const std::string & line,indexed_sparse_matrix_t<int> & 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.set(ligne,colonne,valeur);
}
free(buffer);
return true;
}
bool lire_fichier(const char *filename,indexed_sparse_matrix_t<int> & 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(){
// Initialiser la matrice
typedef indexed_sparse_matrix_t<int> matrix_t;
matrix_t m;
const char *filename="test.txt";
// 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::cout << m << std::endl;
const std::size_t & nb_row = m.get_nb_row();
std::cout <<"nb de lignes" <<nb_row<<std::endl;
return 0;
}
résultat :
./a.out
Lecture de [test.txt]
0 0 0 5 2 8 3 2
0 0 0 8 4 1 7 5
0 0 0 7 4 2 2 3
5 8 7 0 0 0 2 6
2 4 4 0 0 0 3 9
8 1 2 0 0 0 6 7
3 7 2 2 3 6 0 0
2 5 3 6 9 7 0 0
nb de lignes8
" normalemen c une matrice symetrique"
à l'exécution j'obtient une matrice ou a l'affichage il manque la derniere ligne et la derniere colonne, j'ai trouvé ca bizare, j'ai regardé la valeur de nb_row pr connaitre la nombre de ligne ( = 8 dans ce cas de fichier alors ke ca devrai etre 9 jpense ) , je pense qu'il y une ligne en moins !! a moins que j'ai mal compris le fonctionnement du programme é commen nb_row marchait.
de plus dans les boucles d'affcihage kan je rajoute un" nb_row+1 " je vois afficher les lignes et colonnes manquantes mais je pensais ke cétait incorrecte parckil y a un terme en +!
alors SVP aidez moi c urgen!!
merci d'avance.
Configuration: Windows XP Firefox 2.0.0.3
2 réponses
-
le nb_row te donne l'indice du tableau des lignes, mais en C/C++ les
indices commencent à 0 donc la taille est de 9! (8+1 pour l'indice 0 =9)
Ensuite tu ferais mieux de lire caractère par caractère dans un fichier
aussi simple d'après moi, mais c'est personnel
<n°ligne>:\tab(<n°colonne>,<coefficient>)\tab(<n°colonne>,<coefficient>)\tab(<n°colonne>,<coefficient>)...
procedure lire_fichier :
boucle jusqu'à la fin du fichier avec dans la boucle:
-lecture du n°de colone jusqu'au ':'
- appel à lire ligne
procedure lire_ligne:
boucle jusqu'au caractère fin de ligne ou une erreur (mauvais caractère)
-lecture jusqu'au '('
-lecture de valeur jusqu'au ','
-lecture de valeur jusqu'au ')'
tu peux aussi être plus exigent et vérifier vraiment pour avoir un tab mais si il y aura un espace tu pourras plus lire le fichier :(
Avec ça tu auras tout ton fichier sans soucis, c'est un peu prêt ce que tu fais mais avec des complications... -
merci pour ta réponse, mais ce programme la c'était pas vraiment moi qu'il l'avait fait! c'était mamiemando qui m'avait aidé, et c'est lui qui m'avait proposé ce programme ! je ne saurais le modifier!
mais je trouve ca toujours bizarre parcke dans la boucle affichage il faut que je dise jusqu'a +1 a chaque fois!
alors que moi j'aimerais trouver un truc qui me permet de dire que nb_row et nb_col =nombre de lignes et de colonnes et non pas l'indice du tableau, ainsi ce sera plus commode par la suite de mes calculs.
merci-
Le problème c'est que tout le temps tu devras utilisé un indice de tableau pour tes calculs, par contre tu peux faire que ton nb_row et nb_col correspond bien au nombre de ligne et colonne ce qui serait pas si mal car si ton fichier est vide tu le sera ( actuelement si il est vide ou il y a un élément que se passe-t-il ? j'ai pas regardé en détail mais je pense pas que tu veras la différence) mais après quand tu feras ta boucle il faudra la faire temps que indice<nb_row ou indice<nb_col car sinon tu sortiras du tableau (range check error).
-
-