Partage
  • Partager sur Facebook
  • Partager sur Twitter

Remplir une matrice à partir d'un fichier

17 octobre 2019 à 23:27:11

Bonjour à tous :) 

pour clarifier le problème: j'ai deux réseaux d'interaction protéique network1 et network2, et je veux les comparer séquentiellement ,j'ai téléchargé les scores de similarité depuis la base de données. Le fichier est sous le format :

proteine1  proteine2   score de similarité . 

proteine1 appartient au network1, protein2 appartient au network2 et le score de similarité désigne le score de similarité séquentielle entre le 2 protéines.

Je veux lire le fichier et mettre les informations dans une matrice pour l'utilisé après.

		 ifstream inputFile; //le fichier de similarité
		 string protein1,protein2,line, blastFile;
		 float score;
		 int id1,id2;
	     tempBio = new float*[network1.size];//la matrice qui va contenir les informations.
	    for (int c=0; c<network1.size; c++) {
	        tempBio[c]=new float[network2.size];
	    }
	    for (int c1=0; c1<network1.size; c1++) {
	        for (int c2=0; c2<network2.size; c2++) {
	            tempBio[c1][c2]=0;
	        }
	    }
	 blastFile = network1.name;
	 blastFile.append("-");
	 blastFile.append(network2.name);
	 blastFile.append(".sim");
	 inputFile.open(blastFile.c_str()); //blastFile: est le fichier de similarité télécharger.
	 while (getline(inputFile, line))
	 {
	         istringstream tokenizer(line);	        
	         getline(tokenizer, protein1, '\t');
	         id1= network1.getID[protein1];// Dans la premiere partie de code j'ai affecté un id a chaque proteine de deux réseaux de 0 jusque'a la taille de réseaux.
	         getline(tokenizer, protein2, '\t');
	         id2= network2.getID[protein2];
	         tokenizer >> score;         	      
	         tempBio[id1][id2]=score;
	 }
//Pour affiché le contenu de lamatrice 
    ofstream hubTemp("hubAlitemp.txt");
	    
	    	 for (int c1=0; c1<network1.size; c1++) {
	    	 	        for (int c2=0; c2<network2.size; c2++) {
	    	 	        	hubTemp<<network1.getName(c1)<<"  "<<network2.getName(c2)<<"  "<<tempBio[c1][c2]<<endl;

	    	 	        }
	    	 	    }



	    	 




-
Edité par Sara44 18 octobre 2019 à 23:34:49

  • Partager sur Facebook
  • Partager sur Twitter
18 octobre 2019 à 1:05:08

salut fopen et fclose tu as fais ? et fwrite ou fputs ?

-
Edité par alex5956 18 octobre 2019 à 1:06:06

  • Partager sur Facebook
  • Partager sur Twitter
18 octobre 2019 à 9:11:08

Salut,

alex5956 a écrit:

salut fopen et fclose tu as fais ? et fwrite ou fputs ?

-
Edité par alex5956 il y a environ 7 heures

Nous sommes dans la section C++ ici: évite ce genre de cochonnerie avec ce langage ;) (*)

@Sara44 :

1- Avant toute chose : pourrais tu modifier ton message en utilisant le bouton ad-hoc (il prend la forme de </>, et se trouve en deuxième position en partant de la droite juste au dessus de la zone d'édition) pour écrire ton code, cela le rendra beaucoup plus facile à lire ;)

2- On n'utilise plus istringtream depuis C++11 pour la conversion de chaines de caractères en valeurs numériques, mais std::stoui / std::stouil (pour les entiers non signés, voir la doc pour la liste des fonctions ) et std::stof / std::stod pour les réels.

3- En l'état, ton code ne nous est d'aucune utilité, parce que tu utilises un tas d'informations qui nous sont inconnue :

token1 et token2 KESSAKO ??? A priori, je dirais qu'il s'agit de chaines de caractères, vu l'usage que tu en fais.  Mais, comme il s'agit d'une variable temporaire, pourquoi utiliser deux variables différentes? Et, surtout, pourquoi sont-elles déclarées hors de la boucle?

id1 et id2 KESSAKO ??? Quel est le type de ces variables? A quoi servent-elles, vu que tu ne semble pas les utiliser par la suite? Pourquoi sont-elles déclarées hors de la boucle, alors qu'il s'agit visiblement -- de variable temporaires, qui auraient très bien pu être déclarées dans la boucle ?

nework1 et network2 KESSAKO??? Je dirais les instances d'une structures quelconque vu l'usage que tu en fais. Mais que contient-elle? Pourquoi utiliser deux variable différentes? quelle est la différence entre ces deux variables?

mapName KESSAKO ??? A priori, je dirais qu'il s'agit d'une std::map dont la clé a est une chaine de caractères, vu l'usage que tu en fais.  Mais quel est le type de la valeur associée à cette clé? Où cette valeur est-elle définie? Comment peux-tu être sur que la que tu transmet existe dans cette map ? Il eu fallu que nous eumes une connaissance complète des types associés à network1 et network2 pour se faire une idée précise

4- Tu as défini id1 et id2 comme étant les valeurs associées respectivement à network1.mapName[token1] et à network2.mapName[token2] . Pourquoi ne pas les utiliser dans ta formule tempBio[network1.mapName[token1]][network2.mapName[token2]]=token3;?

5- De toutes évidences, il y a une directive using namespace std; qui traine quelque part dans ton code.  ON N'UTILISE PLUS CETTE DIRECTIVE DEPUIS VINGT ANS!!!

Elle a été présentée pour des raisons bien précises lorsque la norme C++98 est sortie, mais elle pose plus de problème que ce qu'elle n'en résoud dans du code actuel.

6- Le compilateur t'a sans doute craché un tas d'erreurs à la figure, pourrait-on les connaitre? Pour qui sait les lire, elles regorgent d'informations utiles ;)

7- Quel drole de format pour un fichier... S'il doit représenter l'état d'une matrice, pourquoi ne pas lui avoir donné une forme correspondant à L ligne de C valeurs, histoire de remplire directement la matrice avec les valeurs correspondantes (quitte à ce que la première ligne du fichier contiennent deux valeurs entières correspondant à la teille respective des lignes et des colonnes de la matrice )?

  • Partager sur Facebook
  • Partager sur Twitter
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
18 octobre 2019 à 11:14:54

2-, Koala, je ne suis pas d'accord. Si les `std::sto{machin_pas_generique}` sont pratiques pour une transformation isolée, pour une série de transformations, ils sont plus lents qu'un istringstream vidé pour chaque chose à extraire. De fait, les flux ont toujours leur utilité.

Et en plus, ils ne sont pas génériques les _string to machin_. Je n'ai pas compris ce qu'a fait le commité là!

-
Edité par lmghs 18 octobre 2019 à 11:15:19

  • Partager sur Facebook
  • Partager sur Twitter
C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
18 octobre 2019 à 19:01:48

Sara44 a écrit:

J'ai utilisé le code mentionné ci-dessous pour lire les lignes, j'ai debuggué le code avec eclipse ça marchait, mais si j'affiche les résultats dans un fichier le code me donne rien.

Tu veux dire que ça fonctionne sous Eclipse, mais pas quand tu l’exécutes en dehors d'Eclipse ?

  • Partager sur Facebook
  • Partager sur Twitter
18 octobre 2019 à 22:54:44

alex5956 a écrit:

salut fopen et fclose tu as fais ? et fwrite ou fputs ?

-
Edité par alex5956 il y a environ 21 heures



  • Partager sur Facebook
  • Partager sur Twitter
19 octobre 2019 à 2:02:08

Je suis assez d'accord avec lmghs, pour bricoler des séries de conversions à la con, le istringstream ça le fait vraiment bien,et c'est plutôt plus pratique que les fonctions dédiées en fait...

Sur le using namespace std, on a utilisé ça à la fin des années 90 pour compiler vite fait, mal fait les programmes écrit avant 1998, avec les compilateurs conformes à la nouvelle norme de c++ (en 1998), qui rangeait la bibliothèque standard dans le namespace std. Le soucis, à l'époque, c'était que les programmes écrit avant 1998 étaient du genre nombreux ;) ça nous donnait du temps pour les mettre à jour., à l'époque c'était justifié. Aujourd'hui, plus de 20 ans après, tous les programmes qui devaient être mis à jour l'ont été, il n'y a donc plus une seule raison valable d'utiliser cette directive qui n'était qu'un pis-aller (ce n'est pas tout à fait vrai, mais les cas d'usage sont des cas extrêmement particuliers, donc extrêmement rares). Je doute franchement que ton programme fasse partie des rares cas particuliers où on ne peut pas éviter cette directive, donc son utilisation est à proscrire.

Un autre truc:

tempBio = new float*[network1.size];

pourrait être avantageusement remplacé par 

std::vector<float> tempBio(network1.size());

Si tout se passe bien, ça ne change quasiment rien. Par contre, en cas de soucis, vector te garantit la libération de la mémoire. Pas besoin non plus de se soucier de libérer la mémoire, vector s'en chargera tout seul comme un grand au moment opportun...


  • Partager sur Facebook
  • Partager sur Twitter
Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug