[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.
A voir également:
- [C++] lecture de fichier pb d'indice
- Fichier bin - Guide
- Fichier epub - Guide
- Fichier rar - Guide
- Comment réduire la taille d'un fichier - Guide
- Fichier .dat - Guide
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...
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
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).