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 puis stocker un fichier en C


Sujet :

C

  1. #1
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 38
    Points : 30
    Points
    30
    Par défaut lire puis stocker un fichier en C
    Bonjour,

    j'ai un probleme avec un projet de bioinfo.

    Je suis censé créer une fonction en C qui peut lire des entrées fasta (fichier texte qui stock des séquences protéiques) dans un fichier et puis qui les stocke (je pensais les stocker dans un tableau à 2 dimensions avec dans l'une les identifiants de ma séquence protéique et dans l'autre la séquence en elle meme)
    (je comptais aussi créer une structure pour faciliter l'exploitation des données apres)

    D'abord voici mon algorithme assez foireux à la base:

    Création d'un tableau de chaine de caractere T[0..1,0..N] (N correspondant à mon nombre de protéine dans le fichier, pour l'instant indéterminé)
    Lire le fichier fasta ligne par ligne
    Alors c'est ici que ça coince: En fait je sais que le mieux serait d'utiliser les piles: empiler quand > et dépiler quand * mais j'avoue que je ne sais pas du tout comment je dois m'y prendre pour coder en C et que ça fonctionne!! Je ne l'ai utiliser qu'en algorithme

    Du coup je pensais utiliser une alternative qui s'avere être foireuse aussi!!
    Si la ligne commence par ">" copier la ligne dans T[1,i]
    sinon tant que non ">" copier la ligne dans T[2,i] en concaténant (et comme la séquence peut etre sur un nombre de ligne variable il faut concaténer)
    tant que non "*" ne pas incrémenter (i++ quand la derniere ligne de séquence a été concaténer (elle finit toujours par " * ") )

    retourner le tableau rempli


    En revanche dans cet algo je ne me suis pas trop préoccupé de la longueur des chaine de caractere dans chaque case de mon tableau, pensant utiliser des pointeurs, mais devrais je allouer dynamiquement de la mémoire? Ou en allouer de maniere plus statique en "tapant" haut, par exemple 600 caracteres (un caractere dans la partie T[2,i] correspond à un acide aminé)?
    Dans ce cas il faudrait utiliser la fonction malloc(strlen()): le probleme c'est que les chaines de caracteres varie en fonction du fichier ; je ne sais pas comment faire pour résoudre ce probleme.









    Bon voici ce que j'ai codé et qui évidement ne fonctionne pas



    >>>>>>>>>STRUCT.H

    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
    #include <stdio.h>
    #include <math.h>
    #include <stdlib.h>
    #include <string.h> 
     
    typedef struct
     
    {
    	char Table[1][N];        // probleme, N inconnu, c'est le nombre de séquence, ça variera en fonction des fichiers!!
    	char id_seq[N];          //avec id_seq un tableau d'une seule dimension fonctionnant comme un pointeur contenant la chaine de caractere correspondant à l'identifiant de ma séquence ; cette chaine de caractere étant de longueur variable
    	char seq[N];             //meme chose
    	Table[1][N]<-id_seq[N];   // je ne sais absolument pas si j'ai le droit de faire ça dans un typedef struct!!!!
    	Table[2][N]<-seq[N];     
     
     
     
     
    }Protein;          // oui pas très inspiré pour le nom de ma structure, je n'ai pas trouver qqch de très parlant ^^
     
     
     
    char stockData(FILE * pFile);
     
    #endif

    >>>>>>>>>>>>>fonction stockdata.h (je ne suis pas sure: dois je enregistrer en .h, en .c
    est ce que ça suffit de l'avoir déclarer dans struct.h pour que le main arrive à la lire?

    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
    #include "struct.h"
     
     
     
    char stockData(FILE * pFile)
                   // ici l'idée c'est que ce soit une fonction qui prenne en argument un pointeur vers un fichier; mais je crois que je vais etre obligé de changer pour un argument comme (char file_name[]), non?
    {
    	FILE * pData= fopen ("pFile", "r", &pFile);         // là j'avoue que je ne suis pas sure de moi, je ne pense pas que l'ordi peut comprendre ma commande, c'est une fonction donc je veux généraliser le nom de mon pointeur vers mon fichier (qui est en argument) par ça
    	if (pData[]=NULL)
     
    	{
     
    		printf("no data detected\n");
     
    		exit(0);
    	}
     
    	else
     
    	{
     
    		printf("the data has been detected\n");
    	}
     
    	fscanf("pFiles","%d",&pFile);        // je ne sais pas du tout si ça peut fonctionner là non plus, même probleme qu'au dessus
    	i<-0;
    	for (i=0, i<N, i++)
    		if ( fgets(Table, Table<N, &pFile)==">")  // je ne sais pas si je peux dre autrement "si la ligne commence par ">" "...
    		{
    			strcopy(fgets() , protein.id_seq[i]);
    		}
    		else
    		{
    			while (fgets() != ">")
    			{
    				strcopy(fgets() , protein.seq[i]);
    				while (fgets() != "*")    // là aussi ça peut poser probleme parce que le "*" n'est qu'en toute fin de ligne!!
    				{
    				strcat(fgets(), protein.seq[i]);
    				}
    			}
    		}
    	}
    	fclose(pFile);
    	return Table[];
     
    }




    >>>>>>>>>>>> le main.c

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include "struct.h"
     
     
     
    int main(int argc, char ** argv)
     
    {
     
    	FILE * pData= fopen ("mydoc", "r", &mydoc.fasta);
    	stockData(pData);
    	return 0;
     
    }



    Voilà j'espere que vous pourrez m'aider! J'ai surtout du mal avec la fonction fgets, je ne vois pas du tout comment l'utiliser ici.

    merci d'avoir lu jusque là ^^

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2004
    Messages : 329
    Points : 608
    Points
    608
    Par défaut
    Citation Envoyé par EaudeRoche Voir le message
    je pensais les stocker dans un tableau à 2 dimensions avec dans l'une les identifiants de ma séquence protéique et dans l'autre la séquence en elle meme
    J'appelle ça un tableau à une dimension moi :-)

    Lire le fichier fasta ligne par ligne
    Alors c'est ici que ça coince: En fait je sais que le mieux serait d'utiliser les piles: empiler quand > et dépiler quand *
    Si tu précisais le format de fichier, ce serait plus facile de t'aider...

    Table[2][N]<-seq[N];
    J'ai jamais vu cette notation "<-" en C, t'es sur de toi ?


    FILE * pData= fopen ("pFile", "r", &pFile); // là j'avoue que je ne suis pas sure de moi, je ne pense pas que l'ordi peut comprendre ma commande, c'est une fonction donc je veux généraliser le nom de mon pointeur vers mon fichier (qui est en argument) par ça
    RTFM "man fopen" : il n'y a que 2 arguments

    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
     
    		if ( fgets(Table, Table<N, &pFile)==">")  // je ne sais pas si je peux dre autrement "si la ligne commence par ">" "...
    		{
    			strcopy(fgets() , protein.id_seq[i]);
    		}
    		else
    		{
    			while (fgets() != ">")
    			{
    				strcopy(fgets() , protein.seq[i]);
    				while (fgets() != "*")    // là aussi ça peut poser probleme parce que le "*" n'est qu'en toute fin de ligne!!
    				{
    				strcat(fgets(), protein.seq[i]);
    				}
    			}
    		}
    	}
    RTFM again :-) : man fgets

    De plus un petit besoin de cours de base de C non ? On ne peut pas comparer des chaines de caractère directement en C

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if("toto" == "toto") // False, c'est une comparaison de pointeur

  3. #3
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 38
    Points : 30
    Points
    30
    Par défaut
    Merci pour votre réponse

    Le fichier à analyser est un fichier texte fasta (mydoc.fasta) avec des chaines de caractere qui se succede:

    typiquement:
    ligne 1 > identifiant "description"
    ligne 2 SLVVNSSISWTQNCSRVAYSVNNKISVISISSSDFNVQSASHSPEFAESILSIQWIDQLL
    ligne 3 VSQGSESVVSWTTLTHVYSILGAYGGPTCLYPTATYFLMGTSKGCVLIFNYNEHLQTILV
    ligne 4 NFGGFSARSLRSLQRQRAILKVMNTIGGVAYLGDVD*
    (le nombre de ligne varie en fonction de la longueur de la protéine)

    les lignes avec la séquence ont au plus 60 caracteres alors que la ligne avec >identifiant ont un nombre très variable de caractere dans la ligne

    Et ces entrées se repetent N fois

    C'était ce que tu voulais savoir?


    Et oui en effet en C pas de <-



    "On ne peut pas comparer des chaines de caractère directement en C"
    Alors qu'est ce que je peux faire à la place?

  4. #4
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 38
    Points : 30
    Points
    30
    Par défaut
    J'ai peut etre trouver quelque chose pour éviter de comparer des chaines de caractere.

    (un algo à demi codé, désolée)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    while fgets()!=NULL
    {
    	getchar(fegets())
    	if !">"
    	{
    		strcpy(fgets(),protein.id_seq)
    	}
    	else
    	{
    		strcat(fgets(),protein.seq)
    	}
    }
    Qu'en pensez vous?


    A moins qu'utiliser les piles soient mieux

  5. #5
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2010
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2010
    Messages : 38
    Points : 30
    Points
    30
    Par défaut
    Je tiens seulement à préciser que ce que j'obtiens en fait au final de cette étape, c'est un tableau de 2 colonnes, chaque case contenant des chaines de caractere.
    La premiere colonne contient le nom des séquences.
    La deuxieme contient la séquence associé à la colonne 1.


    J'ai vraiment du mal à obtenir quoi que ce soit!!

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2004
    Messages : 329
    Points : 608
    Points
    608
    Par défaut
    Euh bon va falloir revoir les bases de C, prends n'importe quel cours pour débutant sur le net ...

    Un exemple vite fait de ce que tu recherches :

    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
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
     
    typedef struct {
      char *identifiant;
      char *sequence;
    } proteine;
     
    typedef struct {
      proteine *content;
      int size;
      int alloc_size;
    } table_prot;
     
    table_prot *create_table() {
      table_prot *table = malloc(sizeof(table_prot));
    #define INITIAL_SIZE 10
      table->content = (proteine *)malloc(INITIAL_SIZE*sizeof(proteine));
      table->size = 0;
      table->alloc_size = INITIAL_SIZE;
     
      return table;
    }
     
    void ajout_proteine( table_prot *table, proteine prot ) {
      // Check enough space
      if(table->size == table->alloc_size) {
        // Augmente la taille allouée
        table->alloc_size += INITIAL_SIZE;
        table->content=realloc(table->content,(table->alloc_size)*sizeof(proteine));
      }
     
      // Initialise le nouvel élement
      table->content[table->size]=prot;
     
      // Enregistre le fait qu'on ait un de plus
      table->size++;
     
    }
     
    // Récupère le ième élement
    proteine *get_proteine(table_prot *table, int i) {
      if(i<table->size) {
        fprintf(stderr,"Error, out of bound : %d\n",i);
        exit(-1);
      }
      return &(table->content[i]);
    }
     
     
    table_prot *read_prot( char *filename ) {
      FILE *fp = fopen(filename,"r");
      if(!fp) {
        perror("impossible de lire le fichier");
        exit(-1);
      } 
     
      // Crée une table
      table_prot *table = create_table();
     
     
      proteine current_prot;
      current_prot.identifiant = NULL;
      current_prot.sequence = NULL;
     
     
      #define BUF_SIZE 65000
      char buffer[BUF_SIZE];
      while(buffer == fgets(buffer,BUF_SIZE,fp)) {
        #define ID_PATTERN "> identifiant "
        if(strncmp(buffer,ID_PATTERN,strlen(ID_PATTERN)) == 0) {
           // Cette ligne est un identifiant
           if(current_prot.identifiant!=NULL) {
              fprintf(stderr,"Erreur, proteine non terminé !\n");
              exit(-1);
           } 
           // Nouvelle proteine avec un nouvel identifiant
           current_prot.identifiant = malloc(strlen(buffer)-strlen(ID_PATTERN));
           current_prot.sequence = NULL;
           strcpy(current_prot.identifiant, buffer+strlen(ID_PATTERN));
        } else {
           // On devrait avoir lu un identifiant !
           if(current_prot.identifiant==NULL) {
              fprintf(stderr,"Erreur, identifiant manquant !\n");
              exit(-1);
           } 
     
           // Taille initiale = 0
           current_prot.sequence = malloc(1);
           current_prot.sequence[0] = '\0';
     
          // Cette ligne est une (partie de) sequence
          char *c = buffer;
     
          // Cherche la fin de la chaine
          while(*c!='*' && *c !='\0') {
    	while(*c!='\n' && *c!='*' && *c !='\0') {
    	  c++;
            }
     	// Longueur de la sequence (sur la ligne en cours)
    	int length = c-buffer;
     
            // Gère la mémoire
            current_prot.sequence = realloc(current_prot.sequence,strlen(current_prot.sequence)+length+1);
     
            // Copy la séquence
            strncat(current_prot.sequence,buffer,length);
     
            // Si fin de ligne, passe à la suivante
            if(*c!='\n') {
               fgets(buffer,BUF_SIZE,fp); // FIXME check error
               c = buffer;
            }
          }
          if(*c=='\0') {
             fprintf(stderr,"Erreur tampon trop petit");
          }
     
          // Fin de séquence, on l'ajoute à la table
          ajout_proteine( table, current_prot );
     
          // Réinitialise
          current_prot.identifiant = NULL;
          current_prot.sequence = NULL;
     
     
        }
      }
     
      return table;
    }
     
     
    int main() {
     
      table_prot *table = read_prot("blabla.txt");
     
      return 0;
    }

Discussions similaires

  1. Réponses: 13
    Dernier message: 29/09/2008, 08h10
  2. [Débutant] Comment lire et stocker un fichier en J2ME?
    Par noutnout53 dans le forum Java ME
    Réponses: 7
    Dernier message: 08/06/2008, 12h57
  3. charger pour stocker un fichier puis le recharger pour l'utiliser
    Par sbitsch dans le forum SQL Procédural
    Réponses: 0
    Dernier message: 23/07/2007, 17h09
  4. Réponses: 9
    Dernier message: 05/04/2005, 09h39
  5. [VB.NET] Installation : lire le path du fichier .msi
    Par Berns dans le forum Windows Forms
    Réponses: 3
    Dernier message: 14/09/2004, 22h25

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