Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 30/03/2008, à 01:24

Mister G

Cas d'utilisation des fichiers en C.

Bonjour à tous !
Je suis en train d'étudier les fichiers en ce moment en C et j'aurais une petite question à vous posez.

Mon fichier a plusieurs colonnes, et je souhaiterai faire une bouble qui me permetterai de mettre dans une variable intermédiaire x, la valeur contenue dans la premiere colonne et dans une variable intermédiaire celle de la deuxième colonne.

Actuelement j'arrive à affichier mon fichier texte à l'écran, mais je ne vois pas comment selectionner pour une ligne les 2 ou 3 chiffres pour x et après les 2 ou 3 chiffres pour y et puis ensuite faire la même chose pour les autres lignes jusqu'à la dernière.

Avez-vous une idée à me conseiller ???

Merci à tous pour votre aide et à bientôt...


PS : Voici le code que j'ai réussit à faire pour afficher le fichier suivant...

########################################################
############descriptif des colonnes du fichier##########
########################################################
########################################################
-x- -y- -nom-
########################################################
########################################################



########################################################
#######################fichier.data#####################
########################################################
########################################################
504 265 AAAAA
469 848 BBBBB
833 575 CCCCC
878 836 DDDDD
276 529 EEEEE
43 796 FFFFF
524  86 GGGGG
168 307 HHHHH
537 295 IIIII
187 453 JJJJJ
43 796 KKKKK
524  86 LLLLL
########################################################
########################################################



########################################################
#########################programme######################
########################################################
########################################################
#include<stdio.h>
#include<stdlib.h>
#include<graph.h>

#define FICHIER "fichier.data"

int main(void){

  FILE* fichier=NULL;
  int c;
  fichier=fopen(FICHIER,"r");

  if((fichier==NULL)){
      fprintf(stderr, "\nErreur: Impossible de lire le fichier %s\n",FICHIER);
      return(EXIT_FAILURE);
  }
 
  while ((c=fgetc(fichier))!=EOF){
    putchar(c);
  }
 
  fclose(fichier);
 
  return EXIT_SUCCESS;
}
########################################################
########################################################


PS 2 : J'espère avoir été les plus compréhensible possible....

#2 Le 30/03/2008, à 10:19

Zapan

Re : Cas d'utilisation des fichiers en C.

Bonjour,

fichier=fopen(FICHIER,"r");

  if((fichier==NULL)){
      fprintf(stderr, "\nErreur: Impossible de lire le fichier %s\n",FICHIER);
      return(EXIT_FAILURE);
  }

Si mes souvenirs de C sont exactes fopen renvois -1 en cas d'erreur, pas NULL.

while((c=fgetc(fichier))!=EOF)&& (c!=' '){

  }

Ceci te permet de n'afficher que le premier chiffre. Pour info ' ' est le code ascii d'un espace (de même 'a' te donne le code ascii de a etc)

Dernière modification par Zapan (Le 30/03/2008, à 10:23)

Hors ligne

#3 Le 30/03/2008, à 18:48

misterg94

Re : Cas d'utilisation des fichiers en C.

merci pour ta réponse, je vais essayer comme ça...

Dernière modification par misterg94 (Le 30/03/2008, à 19:38)

Hors ligne

#4 Le 30/03/2008, à 19:32

rniamo

Re : Cas d'utilisation des fichiers en C.

tu peux aussi récupérer toute ta ligne dans un buffer puis utiliser strtok pour récupérer chaque attribut.


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#5 Le 30/03/2008, à 19:43

misterg94

Re : Cas d'utilisation des fichiers en C.

Alors j'ai un peu modifier un peu mon code, et j'obtiens ça :

(...)
 while(((c=fgetc(fichier))!=EOF)&&(c!='\n')){
     while(((c=fgetc(fichier))!=EOF)&& (c!=' '))
        fscanf(fichier,"%d",&x);
     while(((c=fgetc(fichier))!=EOF)&& (c!=' '))
        fscanf(fichier,"%d",&y);
     printf("x=%d et y=%d\n",x,y); 
   } 
(...)

et j'obtiens ceci :

x=4 et y=65
x=469 et y=48
x=833 et y=75
x=878 et y=36
x=276 et y=29
x=43 et y=96
x=524 et y=96
x=168 et y=7
x=537 et y=95
x=187 et y=53
x=43 et y=96
x=524 et y=96
x=524 et y=96

Donc en fait mon test ne marche pas car certain couple commence par un espace.
Et puis par exemple pour la première ligne il ne prend pas les deux premiers chiffres du x et le premier chiffre de y.

Sinon je vais me renseigner sur google pour la fonction strtok...

encore merci à tous pour l'aide que vous m'apportez !!!

Dernière modification par misterg94 (Le 01/04/2008, à 21:44)

Hors ligne

#6 Le 30/03/2008, à 21:27

misterg94

Re : Cas d'utilisation des fichiers en C.

alors j'ai un petit soucis j'ai compris le principe de la fonction strtok, mais je bloque à mettre une ligne dans une chaîne de caractère temporaire, et de faire ca pour chaque ligne.

int main(void){
(...)
int i;
i=0;
char buffer[50];
(...)

 while(((c=fgetc(fichier))!=EOF)&&(c!='\n')){
    buffer[i]=c;
    i=i+1;    
 }

ça me met uniquement la première ligne dans le buffer et de plus si ma ligne fait moins de caractère ça affiche le reste de buffer.
Avec ce code j'obtiens dans mon terminal :

504 265 AAAAA�^���8����X�����������x���م

Qu'elle serait le meilleur moyen pour résoudre mon problème ???

Dernière modification par misterg94 (Le 01/04/2008, à 21:45)

Hors ligne

#7 Le 30/03/2008, à 21:57

rniamo

Re : Cas d'utilisation des fichiers en C.

fgets (et non fgetc) est plu efficace wink...et prévoit peut être plus que 50 char.

concernant ton "erreur", il ne faut pas oublier de mettre '\0' à la fin de ta chaîne.

edit : mets ton code dans des balise code stp.

Dernière modification par rniamo (Le 30/03/2008, à 22:03)


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#8 Le 30/03/2008, à 22:08

misterg94

Re : Cas d'utilisation des fichiers en C.

Merci pour ta réponse.

Alors voilà où j'en suis, voici mon programme :

#include<stdio.h>
#include<stdlib.h>
#include <string.h>

#define STATIONS "stations.data"
#define TAILLE_MAX 50

int main(void){
  FILE* fichier=NULL;
  int c,x,y;
  char chaine[TAILLE_MAX];
  char *pointeur;
  char *separateur = { " " }; // Le séparateur
  char *buffer;
  int nb=1; 

  fichier=fopen(STATIONS,"r");
  if((fichier==NULL)){
      fprintf(stderr, "\nErreur: Impossible de lire le fichier %s\n",STATIONS);
      return(EXIT_FAILURE);
  }
  else{
    while (fgets(chaine, TAILLE_MAX, fichier) != NULL){
      buffer = strdup ( chaine );
      
      pointeur = strtok( buffer, separateur );
      printf ("mot numero : %d %s\n",nb, pointeur);
      
      while( pointeur != NULL )
	{
	  pointeur = strtok( NULL, separateur );
	  if ( pointeur != NULL )
	    {
	      nb++;
	      printf ("mot numero : %d %s\n",nb, pointeur);
	    }	 
	} 
    }
  }
  fclose(fichier);
  return EXIT_SUCCESS;
}

Et voici ce que ça affiche dans le terminal :

mot numero : 1 504
mot numero : 2 265
mot numero : 3 AAAAA

mot numero : 3 469
mot numero : 4 848
mot numero : 5 BBBBB

mot numero : 5 833
mot numero : 6 575
mot numero : 7 CCCCC

mot numero : 7 878
mot numero : 8 836
mot numero : 9 DDDDD

mot numero : 9 276
mot numero : 10 529
mot numero : 11 EEEEE

mot numero : 11 43
mot numero : 12 796
mot numéro : 13 FFFFF
(...)

Le problème c'est que à chaque saut de ligne nb garde sa valeur...
et je voudrais savoir comment faire maintenant pour mettre le premier mot dans x et le deuxième mot dans y pour chaque ligne sachant que le troisième mot je ne souhaite pas le récupérer.

Encore merci...

Dernière modification par misterg94 (Le 01/04/2008, à 21:45)

Hors ligne

#9 Le 30/03/2008, à 22:11

rniamo

Re : Cas d'utilisation des fichiers en C.

je regarde ce que t'as fait mais ce qui me fait mal aux yeux (te vexes pas, je la faisait aussi cette faute) c'est le fclose :  il faut le mettre dans le if (fichier!NULL) {...;fclose();}


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#10 Le 30/03/2008, à 22:14

rniamo

Re : Cas d'utilisation des fichiers en C.

le 2eme argument de fgets est sizeof(char)*TAILLE_MAX, ça change rien mais c'est plus beau.

separateur ne doit pas être définit comme ça : char separatreur[]=" "; (ça alloue la mémoire contrairement à ta déclaration).

et pour nb, il suffit que tu fasse nb=1 à la fin du while (gets(chaine, TAILLE_MAX, fichier) != NUL)

perso pour analyser un csv qui contient des nombre j'utilise :

double **lecture_csv(const char *fichier, int *nbl, int *nbc, char separateur, GtkWidget * (*creation_bar_progression)(GtkWidget **, const gchar *), void (*progression)(GtkWidget **, gdouble), void (*fermeture_barre_de_progression)(GtkWidget **))
{
	FILE *f;
	char *buf1,c;
	int ligne, i, nb_char, nb_sep;
	long pos;
	double **sortie;
	GtkWidget *prog, *fen, *dialog, *win;

	f=fopen(fichier,"r");
	if (f)
	{
		fen=creation_bar_progression(&prog, "Analyse du fichier (1/5)");
		progression(&prog, 0.0);

		/* On récupère les information sur la taille des données */
		fscanf(f,"%d\n",nbl);
		fscanf(f,"%d\n",nbc);
		(*nbc)++;

		if (*nbl==0 || *nbc==0)
			return NULL;

		if ( !(sortie=(double **)malloc(sizeof(double *)*(*nbl))) )
			erreur_memoire(3);

		/* On initialise la ligne courante du tableau */
		ligne=0;
		for(i=0;i<=*nbl;i++)
		{
			pos=ftell(f);
			nb_char=0;
			nb_sep=0;
			
			fflush(f);//vérifier si utile
			
			/* On calcule le nombre de caractères de la ligne */
			do
			{
				c=fgetc(f);
				nb_char++;
				if (c==separateur)
					nb_sep++;

			}while(c!='\n' && c!=EOF);
			nb_char++; /* \0 */
			
			fflush(f); //vérifier si utile

			/* on écrit la ligne contenue dans le buffer dans le tableau de sortie.
			   Si la ligne est vide on n'imcrémente pas ligne donc on réécrira dessus au prochain tour de boucle */
			if ( nb_sep==(*nbc-1) )
			{
				fseek(f,pos,SEEK_SET);

				if ( !(buf1=(char *)malloc(sizeof(char)*nb_char)) )
					erreur_memoire(4);

				fgets(buf1,sizeof(char)*nb_char,f);

				buf1=bouche_trous(buf1,separateur,'0');

				if ( !(sortie[ligne]=(double *)malloc(sizeof(double)*(*nbc+1))) )
					erreur_memoire(5);

				enregistre_ligne(sortie,buf1,ligne,separateur);
				free(buf1);
				ligne++;
			}
			progression(&prog,(gdouble) (1.0*i/(*nbl)) );
		}
		fclose(f);

		fermeture_barre_de_progression(&fen);
		
		if (!ligne)
		{
			win=gtk_window_new(GTK_WINDOW_TOPLEVEL);
			dialog=gtk_message_dialog_new(GTK_WINDOW(win),GTK_DIALOG_MODAL,GTK_MESSAGE_INFO,GTK_BUTTONS_OK,"Verifier le separateur\n(Edition -> Modifier)\nAucune lignes enregistree.");
			switch(gtk_dialog_run(GTK_DIALOG(dialog)))
			{											
				default:
				break;
			}
			gtk_widget_destroy(dialog);
			gtk_widget_destroy(win);
			
			return NULL;
		}
		
		if ( !(sortie=(double **)realloc(sortie,sizeof(double *)*ligne)) )
			erreur_memoire(6); 
	}
	else
	{
		fichier_non_trouve();
		return NULL;
	}

	return sortie;
}

PS : un csv c'est un fichier dont les colonnes sont séparé par des ',' ou ';'.
PS2 : pour mettre les mot 1 et 2 dans x et y tu peux :
        1) les récupérer dans un buffer
        2) faire x (ou y) =atof (ou atoi pour les int) (chaine qui contient le mot que tu veux);

NB : x ou y ne contiendra qu'un des mot à la fois, ce n'est pas un tableau.

Dernière modification par rniamo (Le 30/03/2008, à 22:18)


< Quelques un des mes programmes  | Cuisine Facile (pour les gourmands) | Fast MVC for PHP >
        \   ^__^
         \  (o o)\_______
            (___)\            )\

Hors ligne

#11 Le 01/04/2008, à 21:56

misterg94

Re : Cas d'utilisation des fichiers en C.

Je vous écris ce message pour vous dire que j'ai réussi à récupérer toutes les valeurs du fichier que je souhaitais.
Je vous montre mon code :

#include<stdio.h>
#include<stdlib.h>
#define STATIONS "stations.data"


char *sous_chaine (const char *s, unsigned int start, unsigned int end){
   char *new_s = NULL;
   if (s != NULL && start < end){
     new_s = malloc (sizeof (*new_s) * (end - start + 2));
     if (new_s != NULL){
       int i;
       for (i = start; i <= end; i++){
	 new_s[i-start] = s[i];
       }
     }
     else{
       fprintf (stderr, "Memoire insuffisante\n");
       exit (EXIT_FAILURE);
     }
   }
   return new_s;
}



int lire_station(){
  
  int x;/*variable qui contiendra la valeur de x une fois convertie*/
  int y;/*variable qui contiendra la valeur de y une fois convertie*/
  const int taille_max=50; /*taille d'une ligne du fichier*/
  FILE* fichier=NULL; 
  char* tmp_x=NULL;/*chaîne de caractère temporaire qui va contenir la position x de la sation */
  char* tmp_y=NULL;/*chaîne de caractère temporaire qui va contenir la position y de la sation */
  char* nom=NULL;/*chaîne de caractère qui va contenir le nom de la station*/
  char buffer[taille_max];
    
  fichier=fopen(STATIONS,"r");/*on ouvre le fichier station.data"*/
  
  if((fichier==NULL)){ /*si le fichier ne peut pas être ouvert renvoie une erreur dans stderr*/
    fprintf(stderr, "\nErreur: Impossible de lire le fichier %s\n",STATIONS);
    return(EXIT_FAILURE);
  }
  else{
    while(fgets(buffer,taille_max, fichier) != NULL){/*tant que l'on n'arrive pas à la fin du fichier, on le lit ligne par ligne que l'on place temporairement dans une chaîne de caractere buffer*/
      
      tmp_x=sous_chaine(buffer,0,2);/*on créer une sous-chaîne qui ne contient que les valeur de x*/
      x=strtol(tmp_x,(char **) NULL,10);/*on convertie la sous-chaîne qui contient la valeur de x en entier*/
      
      tmp_y=sous_chaine(buffer,4,6);/*on créer une sous-chaîne qui ne contient que les valeur de y*/
      y=strtol(tmp_y,(char **) NULL,10);/*on convertie la sous-chaîne qui contient la valeur de y en entier*/
      
      nom=sous_chaine(buffer,8,45);/*on créer une sous-chaîne qui ne contient que le nom des stations*/
      
      printf("x=%d; y=%d; nom=%s",x,y,nom);/*permet de vérifier à l'écran toutes les données*/
    }
  }
  fclose(fichier);/*fermeture du fichier station.data*/
}



int main(void){
  lire_station();/*appelle de la fonction lire_station qui permet d'extraire les coordonnées et le nom de chaque station*/
  return EXIT_SUCCESS;
}

Si jamais vous avez des questions...
Encore merci à tous pour votre aide, et à bientôt sur le forum...

Hors ligne

#12 Le 02/04/2008, à 16:50

misterg94

Re : Cas d'utilisation des fichiers en C.

Zapan a écrit :

Si mes souvenirs de C sont exactes fopen renvois -1 en cas d'erreur, pas NULL.

J'ai vérifié, et fopen renvois bien NULL en cas d'erreur tongue.

Hors ligne