IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

lire une ligne a partir d'un fichier et la mettre dans un tableau de réels


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Inscrit en
    Février 2011
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 61
    Par défaut lire une ligne a partir d'un fichier et la mettre dans un tableau de réels
    Bonsoir tout le monde,

    Voila je suis a la recherche d'un code pour faire ce qui suit :
    -> lire un fichier texte ligne par ligne
    -> mettre chaque ligne dans un tableau de réels

    Mon fichier a la forme suivante :
    0.000484 0.265439 0.000000 0.000000
    0.023867 0.168913 0.000000 0.000000
    0.000000 0.001181 0.201835 0.000000
    J'aimerai avoir a la sortie du programme une matrice de réels
    qui contient ces valeurs pour les utiliser dans un calcul de distance.

    Si quelqu'un a une idée je prends
    Merci d'avance

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Il faudrait que tu te renseignes sur les vectors et que tu fasse des vector de vector.
    http://cpp.developpez.com/faq/cpp/?page=STL


    Il faudrait aussi que tu regardes la lecture de fichier (très simple) :
    http://cpp.developpez.com/faq/cpp/?page=fichiers

    Après, je ne penses pas que l'algorithme puisse réellement te poser des problèmes.

    EDIT : un autre lien qui peut être utile :
    http://cpp.developpez.com/faq/cpp/?p...NGS_convert_to

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 4
    Par défaut
    Bonjour,

    Deux cas se présentent selon si vous connaissez la taille de la matrice à l'avance ou pas.

    La taille de la matrice est connue
    Si la taille est fixée, vous pouvez utiliser std::array :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #include <array>
    #include <iostream>
     
    template<size_t N>
    std::istream& operator>>(std::istream &in, std::array<std::array<double,N>,N> &rhs){
    	for(size_t y=0; y<N; ++y)
    		for(size_t x=0; x<N; ++x)
    			in >> rhs[y][x];
    	return in;
    }
     
    int main(){
    	// Taille connue à la compilation : 4x4.
    	std::array<std::array<double,4>,4> matrice;
    	std::cin >> matrice;
    }
    Dans ce cas, le fait que les données soit sur une ligne ou plusieurs ne change rien.
    std::array n'est apparu qu'avec C++11, vous pouvez utiliser std::tr1::array, boost::array ou même des tableaux C (double[4][4]) à la place.

    Boost.uBlas (bibliothèque permettant de manipuler facilement matrices et vecteurs) insère automatiquement la taille des matrices affichées, cela permet une lecture très simple, par exemple si vous insérez "largeur hauteur" au début de votre fichier (e.g. "4 4"), vous pouvez lire vos matrices dans un vector (à défaut d'utiliser Boost.uBlas) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <iostream>
    #include <vector>
     
    int main(){
    	size_t largeur, hauteur;
    	std::cin >> largeur >> hauteur;
    	std::vector<std::vector<double> > matrice(hauteur, std::vector<double>(largeur));
    	for(size_t y=0; y<hauteur; ++y)
    		for(size_t x=0; x<largeur; ++x)
    			in >> rhs[y][x];
    }
    Là encore, le fait que les données soit sur plusieurs lignes n'est pas pris en compte.

    La taille de la matrice n'est pas connue
    Si possible, évitez ce cas, il suffit d'insérer la taille de la matrice au début du fichier.

    Si toute fois vous devez travailler avec des matrices de taille inconnues, plusieurs solutions s'offrent à vous, dans tous les cas j'ai supposé la lecture dans un vecteur de vecteur (std::vector<std::vector<double> >).

    La solution la plus simple est d'utiliser un std::istringstream avec std::getline :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #include <cassert>
    #include <iostream>
    #include <iterator>
    #include <sstream>
    #include <string>
    #include <vector>
     
    int main(){
    	std::vector<std::vector<double> > matrice;
    	std::string ligne;
    	std::istream_iterator<double> stream_end;
     
    	while(std::getline(std::cin, ligne)){
    		// Une ligne supplémentaire a été lue.
    		matrice.push_back(std::vector<double>());
    		// Reservation de la mémoire nécessaire si connue.
    		matrice.reserve(matrice.empty()?0:matrice.front().size());
     
    		std::istringstream ligne_stream(ligne);
    		std::copy(std::istream_iterator<double>(ligne_stream), stream_end, std::back_inserter(matrice.back()));
     
    		// Vous pouvez éventuellement vérifier si les lignes sont de même longueur*:
    		assert(matrice.size()==1 || matrice.back().size()==matrice.front().size());
    	}
    }
    Pour ceux se sentant poète, il est possible d'enrober le tout dans un iterator… *tordu*
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    #include <cassert>
    #include <iostream>
    #include <iterator>
    #include <sstream>
    #include <string>
    #include <vector>
     
    template <class T, class charT = char, class traits = std::char_traits<charT>, class Distance = std::ptrdiff_t>
    class istream_line_iterator: public std::iterator<std::input_iterator_tag, std::vector<T>, Distance, const std::vector<T>*, const std::vector<T>&> {
    public:
    	typedef charT char_type;
    	typedef traits traits_type;
    	typedef std::basic_istream<charT,traits> istream_type;
    	istream_line_iterator(): in_stream(nullptr), ok(false) {}
    	istream_line_iterator(istream_type& s): in_stream(&s), ok(s) {}
    	istream_line_iterator(const istream_line_iterator& x) = default;
    	~istream_line_iterator() = default;
    	const std::vector<T>& operator*() const { return value; }
    	const std::vector<T>* operator->() const { return &(operator*()); }
    	istream_line_iterator<T,charT,traits,Distance>& operator++(){
    		read();
    		return *this;
    	}
    	istream_line_iterator<T,charT,traits,Distance> operator++(int){
    		istream_line_iterator tmp(*this);
    		read();
    		return tmp;
    	}
    	bool operator==(const istream_line_iterator<T,charT,traits,Distance> &rhs) const {
    		return (!ok&&!rhs.ok) || in_stream==rhs.in_stream;
    	}
    	bool operator!=(const istream_line_iterator<T,charT,traits,Distance> &rhs) const {
    		return !(operator==(rhs));
    	}
     
    private:
    	void read(){
    		value.clear();
    		if(ok){
    			std::string line;
    			std::getline(*in_stream, line);
    			std::istringstream iss(line);
    			std::copy(std::istream_iterator<double>(iss), std::istream_iterator<double>(), std::back_inserter(value));
    		}
    		ok = in_stream && *in_stream;
    	}
     
    	std::basic_istream<charT,traits>* in_stream;
    	std::vector<T> value;
    	bool ok;
    };
     
    // En deux lignes :
    int main(){
            std::vector<std::vector<double> > matrice;
            std::copy(istream_line_iterator<double>(std::cin), istream_line_iterator<double>(), std::back_inserter(matrice));
    }
    Mais je pense que je dérive un peu là.

    Il est aussi possible d'utiliser std::istream::peek pour éviter quelques copies…

  4. #4
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Je ne connais pas le niveau de maryem_kh, mais si on suppose qu'il est débutant, il est possible qu'il ne comprenne pas tout à fait la totalité de ton code (comme les templates, ou la surcharge de l'opérateur par exemple).

    Il aurait été bien d'attendre qu'il lise un peu les liens que j'ai proposés et qu'il essaye déjà par lui-même avant de lui proposer des améliorations et des solutions plus adaptées à son problème.

    Là, tu apportes directement la solution et il n'a qu'à copier-coller ton code sans forcément comprendre ce que tu as fait.

    On est là pour aider pas pour faire le travail à sa place.
    Dans un domaine tel que l'informatique, si on n'apprend pas à s'auto-documenter ou à chercher par soit-même, il vaut mieux changer de métier.
    Et puis c'est en essayant et en faisant des erreurs qu'il apprendra, pas en recevant des bout de codes tout prêt.

    EDIT : D'ailleurs rien nous dit que sa question ne fait pas l'objet d'un morceau d'exercice qu'il doit faire dans le cadre de ses études. Et si les professeurs donnent les exercices sans donner les réponses, il y a une bonne raison^^

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par ÉJLS. Voir le message
    Deux cas se présentent selon si vous connaissez la taille de la matrice à l'avance ou pas.
    Le critère taille connue ou pas n'est pas le seul critère. Il faut aussi se poser des questions de taille grande ou pas.

    Et même dans le cas où on choisit une vector, un simple vector où l'on accède à la case i,j par v[i*nbColumns+j] est souvent préférable à une vecteur de vecteurs.


    Citation Envoyé par maryem_kh Voir le message
    bonsoir tout le monde,
    Voila je suis a la recherche d'un code pour faire ce qui suit :
    lire un fichier texte ligne par ligne
    mettre chaque ligne dans un tableau de réels
    mon fichier a la forme suivante :
    0.000484 0.265439 0.000000 0.000000
    0.023867 0.168913 0.000000 0.000000
    0.000000 0.001181 0.201835 0.000000
    j'aimerai avoir a la sortie du programme une matrice de réels
    qui contient ces valeurs pour les utiliser dans un calcul de distance.
    Si quelqu'un a une idée je prends
    Il y a en fait deux questions dans ta question :
    - Comment vas-tu représenter en mémoire cette matrice. Je conseille personnellement dans ce genre de situations un simple vecteur correspondant à une mise à plat de ta matrice (cf plus haut).
    - Comment vas-tu lire le fichier pour la remplir
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2012
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2012
    Messages : 4
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Je ne connais pas le niveau de maryem_kh, mais si on suppose qu'il est débutant, il est possible qu'il ne comprenne pas tout à fait la totalité de ton code (comme les templates, ou la surcharge de l'opérateur par exemple).
    [...]
    Là, tu apportes directement la solution et il n'a qu'à copier-coller ton code sans forcément comprendre ce que tu as fait.
    Hum, j'ai supposé que maryem_kh avait un niveau pas trop mauvais et qu'il allait chercher par lui même ce qu'il ne comprenait pas. Mais en effet, j'ai peut être mal supposé.

    Citation Envoyé par JolyLoic Voir le message
    Le critère taille connue ou pas n'est pas le seul critère. Il faut aussi se poser des questions de taille grande ou pas.
    Bien sûr, je ne faisais que diviser ma réponse en deux. Évidement, there's more than one two ways to do it.

  7. #7
    Membre actif
    Inscrit en
    Février 2011
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 61
    Par défaut
    Merci a vous tous ,
    j'ai arrivée a implementer cette fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    void fenprincipale::download_datas(int num)
    {
     
     
            ifstream fichier("histhsv.txt", ios::in);
            int col ;
            if(fichier)  // si l'ouverture a fonctionné
     
            {   cout<<"ouverture" ;
                string ch;  // déclaration d'une chaîne qui contiendra la ligne lue
                    getline(fichier, ch);  // on met dans "contenu" la ligne
                      col=nbre_colonne((char*)ch.c_str());
            }
            printf("col = %d",col );
            // on ouvre en lecture
                  float **tt;
                    if(fichier)  // si l'ouverture a fonctionné
                    {  for(int i=0;i<4;i++)
                        {
                            string contenu;  // déclaration d'une chaîne qui contiendra la ligne lue
                            getline(fichier, contenu);  // on met dans "contenu" la ligne
                            float* tab ;
                            tab=string_to_float((char*)contenu.c_str());
                            for(int k=0;k<col;k++)
                            {   printf("\n tab=%f",&tab[k]);
                                tt[i]=&tab[k] ;
                                printf("%f",&tt[i][k]);
                                //printf("k=%d\n",k);
                            }
     
                        }
     
                        fichier.close();
                         cout<<endl<<"fermer fichier" ;
                    }
                    else
                            cerr << "Impossible d'ouvrir le fichier !" << endl;
     
                    cout<<endl<<"fin calcul";
                    cout<<endl<<"val= t"<<tt[34][12];
     
    }
    la fonction qui transforme une ligne en un tableau de float est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    float* string_to_float(char* chaine)
    {
       string s=chaine ;
     
    int cc=nbre_colonne(chaine);
    float tab[cc];
     
     
    for(int j=0;j<cc;j++)
     
    {   string X;
        X=s.substr(j*8+j,8);
     
        //strcpy(chaine+j*8+j, X);
        tab[j]=atof(X.c_str());
        cout<<endl<<"tab["<<j<<"]= "<<tab[j] ;
     
    }
    return tab ;
    }
    Avec la fonction nbre_colonne() est la fonction qui calcule le nombre d'espaces.
    Lors de l'execution , j'obtiens ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    ouverturecol = 11
    tab[0]= 0.000164
    tab[1]= 0.10178
    tab[2]= 0.333
    tab[3]= 0.004
    tab[4]= 0.054
    tab[5]= 0.0076
    tab[6]= 0.98
    tab[7]= 0.0023
    tab[8]= 0.0021
    tab[9]= 0.23
    tab[10]= 0.21
     tab=0.0000000.000000
     tab=0.0000000.000000
     tab=0.0000000.000000
     tab=0.0000000.000000
     tab=0.0000000.000000
     tab=0.0000000.000000
     tab=0.0000000.000000
     tab=0.0000000.000000
     tab=0.0000000.000000
     tab=0.0000000.000000
     tab=0.0000000.000000terminate called after throwing an instance of 'std::bad_cast'
      what():  std::bad_cast
    Quelqu'un a une idée pourquoi j'obtiens ces zeros ??
    et d'ou vient cet erreur ??

  8. #8
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Tu as une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    float * fonction(char *)
    Or tu l'utilise comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    fonction(String.c_str());
     
    float * fonction(char * c)
    {
         string s = c;
    }
    Il est plus simple de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    fonction(String);
     
    float * fonction(string & s)
    {
    }
    Sinon tu retournes un float * et non un float[], tu va donc copier uniquement le pointeur vers la première case de ton tableau de float.
    Ton tableau de float est local, il sera donc libéré à la fin de la fonction, tu risques donc un segfault.

    Il vaut mieux prendre en paramètre un pointeur (ou une référence) sur un vecteur pour pouvoir ajouter tes éléments à la suite.

    Sinon, si ton nombre de colonne est constante, tu as juste à faire une boucle du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    //tant qu'on est pas à la fin du fichier
    fichier >> monFloat;
    //stocker le float dans ton tableau.
    //fin tant que
    Dans ton cas, autant utiliser un std::vector et à chaque ligne (que tu détectera grâce à compteur incrémenté à chaque lecture de float en faisant un %nbColonne), rallouer des éléments avec capacity.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    printf("\n tab=%f",&tab[k]);
    Pas de '&', tu veux afficher un élément du tableau et non l'adresse d'un élément de ton tableau.

  9. #9
    Membre actif
    Inscrit en
    Février 2011
    Messages
    61
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 61
    Par défaut
    bonjour,
    j'ai corrigé la fonction mais j'ai pas compris comment retourner le tableau : float * ou float[] ? et aprés comment remplir la matrice avec ces valeurs ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 6
    Dernier message: 25/11/2014, 10h22
  2. [Débutant] Lire une ligne bien précise d'un fichier
    Par valarko dans le forum MATLAB
    Réponses: 2
    Dernier message: 14/08/2009, 09h56
  3. Supprimer une ligne a partir d'un fichier texte
    Par Msysteme dans le forum C#
    Réponses: 10
    Dernier message: 23/06/2009, 17h05
  4. Réponses: 9
    Dernier message: 05/11/2007, 11h05
  5. Réponses: 3
    Dernier message: 09/09/2006, 13h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo