Langage C - Afficher une série de caracteres

Résolu/Fermé
scolphi Messages postés 36 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 18 mai 2008 - 14 avril 2008 à 23:09
scolphi Messages postés 36 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 18 mai 2008 - 16 avril 2008 à 09:36
Bonjour,

Je programme en C sous dev C++.
Jai un fichier fichiertournee.txt dont chaque ligne est ainsi faite :
un nombre entier suivi d'une série de caracteres, d'espaces, de tabulations, de nombres dans le désordre et enfin un saut de ligne.
J'aimerai que l'utilisateur rentre un nombre, que le programme lise le fichier, reconnaisse le nombre voulu et affiche uniquement le reste de la ligne en question jusqu'au saut de ligne.
Je suis bloqué depuis longtemps dessus alors si vous pouviez me dépanner ça serait sympa !
A voir également:

10 réponses

Tu peux aussi tester ça, qui utilise la fonction strncpy() au lieu de la fonction lire_champs() qui est de mon invention.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LONG_BUF  256        /* longueur du buffer des fichiers */
  

int main()
{
   FILE *fp;
   char chaine1 [LONG_BUF], fich [LONG_BUF], mot [11], *chaine2;
   char s [11];
   /*ouverture du fichier*/
   /*test si le fichier existe*/
   printf ("Fichier a explorer : ");
   gets (fich) ;
   if (strcmp (fich, "") == 0)      exit (0);
	     fp = fopen (fich, "r");
	     if (fp == NULL)
		{
		fclose (fp);
		fprintf (stderr,"\nERREUR D'OUVERTURE DU FICHIER %s\n", fich);
		getch();
		exit (1);
		}
   fclose(fp);
   /*boucle de recherche du nombre dans le fichier*/
   do
   {
     printf("\nEntrer le nombre recherche ou 0 pour quitter : ");
     scanf("%10s", mot);
     if (strcmp(mot,"0")!=0)
	     {
	     fp = fopen (fich, "r");
		while (fgets (chaine1, LONG_BUF, fp) != NULL)
			 {
			 strncpy(s,chaine1,strlen(mot));
			 s[strlen(mot)] = '\0';
			 if (strcmp(s,mot)==0)
			      {
			       chaine2=&chaine1[strlen(mot)];
			       printf("%s\n",chaine2);
			       break;
			      }
			  }
		    if (strcmp(s,mot) !=0 ) printf("non trouve\n");

		 fclose (fp);
	     }
   }
   while (strcmp(mot,"0")!=0);

return 0;
}

Je crois qu'on a fait le tour de la question, à toi de voir laquelle des solutions répond le mieux à ton problème.
3
scolphi Messages postés 36 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 18 mai 2008 2
16 avril 2008 à 09:36
Merci bcp ;)
0
Bonsoir,

Est ce que tu peux afficher une ligne de ton txt et indiquer le nombre cherché, pour voir à quelle place il se trouve dans le texte.

A+.
2
scolphi Messages postés 36 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 18 mai 2008 2
15 avril 2008 à 00:12
123 Ville 1 : Rouen Ville 2 : Verin

Voici au hasard une ligne du fichier.
Pouriez vous me montrer comment, lorque l'on rentre le nombre 123, afficher "Ville 1 : Rouen Ville 2 : Verin" svp ?
0
Bonjour,

Regarde ce que j'ai fait, si ça peut t'aider
Le prog demande le nom du fichier à explorer
Puis dans une boucle, le nombre à trouver dans le fichier, jusquà ce que tu entre 0 pour finir.

j'ai testé avec Borland C++ 3.0 et ça fonctionne bien
J'ai testé avec Dev C++ et le test d'erreur de fichier ne marche pas si tu entre un mauvais nom.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LONG_BUF  256        /* longueur du buffer des fichiers */
  
int instr(); 

int main()
{
   FILE *fp;
   char chaine1 [LONG_BUF], fich [LONG_BUF], mot [11], *chaine2;
   int pos;
   /*ouverture du fichier*/
   /*test si le fichier existe*/
   printf ("Fichier a explorer : ");
   gets (fich) ;
   if (strcmp (fich, "") == 0)      exit (0);
	     fp = fopen (fich, "r");
	     if (fp == NULL)
		{
		fclose (fp);
		fprintf (stderr,"\nERREUR D'OUVERTURE DU FICHIER %s\n", fich);
		getch();
		exit (1);
		}
   fclose(fp);
   /*boucle de recherche du nombre dans le fichier*/
   do
   {
     printf("\nEntrer le nombre recherche ou 0 pour quitter : ");
     scanf("%10s", mot);
     if (strcmp(mot,"0")!=0)
	     {
	     fp = fopen (fich, "r");
		while (fgets (chaine1, LONG_BUF, fp) != NULL)
			 {
			  pos=instr(chaine1,mot);
			  if (pos > -1)
			      {
			       chaine2=&chaine1[pos+strlen(mot)];
			       printf("%s\n",chaine2);
			       break;
			      }
			  }
		 if (pos == -1) printf("non trouve\n");

		 fclose (fp);
	     }
   }
   while (strcmp(mot,"0")!=0);

return 0;
}


/*si sous_chaine est dans chaine,
  retourne position 1er caratère de sous_chaine a partir de 0,
  sinon retourne -1*/

int instr (chaine , sous_chaine)
char *chaine;
char *sous_chaine;
{
   int l , m , n ,i ,j ;
   l = strlen(chaine);
   m = strlen(sous_chaine);
   n = -1;
   if ((m > l) || (m == 0) || (l == 0)) return(n);
   j = -1;
   while (j<l)
   { 
    i = 0; j = j+1; 
    while ((sous_chaine[i]==chaine[j]) && (i<m) && (j<l))
      {
        i = i+1; j = j+1;
      }
      if ( i == m)
         {
          n = j-m;
          return(n);
         }
   }
return(n);
}


Dis moi ce que tu en penses.

A+.
2
scolphi Messages postés 36 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 18 mai 2008 2
15 avril 2008 à 13:50
Ok merci.. Mais il reste un probleme.
A la base, je rentre mon nombre et je veut afficher tout le reste de la ligne.
Mais imaginons que j'ai :

1 Ville 1 : Rouen Ville 2 : Bordeaux Ville 3 : Toulouse Ville 4 : Verin

2 Ville 1 : Wimy Ville 2 : Lyon

Je rentre dans ton programme le chiffre 2 et il m'affiche ": Bordeaux Ville 3 : Toulouse Ville 4 : Verin"
au lieu de "Ville 1 : Wimy Ville 2 : Lyon"..

Seul le premier nombre de la ligne doit être pris en compte par le programme..
0
mamiemando Messages postés 33073 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 16 avril 2024 7 748
14 avril 2008 à 23:33
L'idéal ce serait de lire le fichier et de le stocker dans une std::map avec pour clé l'entier et en data la chaîne qui suit. C'est très facile à faire en C++ mais pas vraiment en C (il faut coder un arbre). Si tu t'autorises à relire le fichier à chaque requête (ce qui est plus lent mais raisonnable si le fichier est court), il suffit de lire le fichier ligne par ligne avec un fscanf et regarder si l'entier demandé correspond à l'entier lu.

Précise-moi si on se trouve dans un de ces deux contextes et si oui lequel.

Bonne chance
1
scolphi Messages postés 36 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 18 mai 2008 2
14 avril 2008 à 23:39
Le fichier txt est plutôt court. Je pensais à un fscanf mais je voit pas trop comment l'utiliser.
Une autre solution serait d'afficher caractere par caractere l'ensemble de la ligne qui suit le nombre mais je sais pas faire non plus :/
p.s : le nombre et le reste de la ligne sont séparé par une tabulation.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
scolphi Messages postés 36 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 18 mai 2008 2
15 avril 2008 à 11:20
svp !
1
bonjour,

tu es obligé de le faire en C ? parce que je pense qu'en batch ce serait plus simple à mettre en oeuvre !
1
scolphi Messages postés 36 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 18 mai 2008 2
15 avril 2008 à 12:14
Je sais pas ce que c'est le batch.. Je doit le faire en C oui :/
0
OK, je refléchis un petit instant
1
OK,

Essaye comme ça, remplace tout le code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LONG_BUF  256        /* longueur du buffer des fichiers */
  
int instr(); 
char *lire_champs ();

int main()
{
   FILE *fp;
   char chaine1 [LONG_BUF], fich [LONG_BUF], mot [11], *chaine2;
   int pos;
   /*ouverture du fichier*/
   /*test si le fichier existe*/
   printf ("Fichier a explorer : ");
   gets (fich) ;
   if (strcmp (fich, "") == 0)      exit (0);
	     fp = fopen (fich, "r");
	     if (fp == NULL)
		{
		fclose (fp);
		fprintf (stderr,"\nERREUR D'OUVERTURE DU FICHIER %s\n", fich);
		getch();
		exit (1);
		}
   fclose(fp);
   /*boucle de recherche du nombre dans le fichier*/
   do
   {
     printf("\nEntrer le nombre recherche ou 0 pour quitter : ");
     scanf("%10s", mot);
     if (strcmp(mot,"0")!=0)
	     {
	     fp = fopen (fich, "r");
		while (fgets (chaine1, LONG_BUF, fp) != NULL)
			 {
            if (strcmp(lire_champs(chaine1,1),mot)==0)
			      {
			       pos=instr(chaine1,mot);
 			       chaine2=&chaine1[pos+strlen(mot)];
			       printf("%s\n",chaine2);
			       break;
			      }
			  }
		 if (strcmp (lire_champs (chaine1,1) ,mot) !=0 ) printf("non trouve\n");

		 fclose (fp);
	     }
   }
   while (strcmp(mot,"0")!=0);

return 0;
}


/*si sous_chaine est dans chaine,
  retourne position 1er caratère de sous_chaine a partir de 0,
  sinon retourne -1*/

int instr (chaine , sous_chaine)
char *chaine;
char *sous_chaine;
{
   int l , m , n ,i ,j ;
   l = strlen(chaine);
   m = strlen(sous_chaine);
   n = -1;
   if ((m > l) || (m == 0) || (l == 0)) return(n);
   j = -1;
   while (j<l)
   { 
    i = 0; j = j+1; 
    while ((sous_chaine[i]==chaine[j]) && (i<m) && (j<l))
      {
        i = i+1; j = j+1;
      }
      if ( i == m)
         {
          n = j-m;
          return(n);
         }
   }
return(n);
}

char *lire_champs (ligne, num_col)
char *ligne;
int num_col;
{
   char car;
   static char champ [LONG_BUF];
   int c, i, n, k;
   c = 0;  i = 0;   strcpy (champ, "");   n = strlen (ligne);  k = 0;
   if (n==0) return(champ);
   car = ' ';
   while (c < num_col  &&  i < n)       
   {
      while (car <= 32  &&  i < n)     car = ligne [i++];         
      if (i <= n)      c++;
      if (c == num_col)     break;
      while (car > 32  &&  i < n)      car =ligne [i++]; 
   }
   while (car > 32  &&  i < n)
   {
       champ [k++] = car;     car = ligne [i++]; 
   }
   if (c == num_col  &&  i >= n)        champ [k++] = car;
   champ [k] = '\0';
   return (champ);
}
1
scolphi Messages postés 36 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 18 mai 2008 2
15 avril 2008 à 14:42
Merci !!
Je vais essayer de comprendre maintenant. Je ne pensais pas que ça aurait été si compliqué..
0
Je t'explique grosso-modo

on lit le fichier ligne par ligne avec fgets()
on regarde si le champ n°1 de la ligne correspond au nombre cherché, c'est le role de lire_champs()
si ça correspond, on regarde sa position dans la ligne avec instr() (au cas ou il y aurait des espaces en début de ligne)
d'apres sa position on calcule l'adresse du début du texte qu'on veut afficher : chaine2=&chaine1[pos+strlen(mot)];

on aurait pu se passer de la fonction instr() si on était sur que le nombre était tout au début de la ligne (sans espaces devant).

Pour le reste, c'est de la manipulation des carctères.

A+.
1
scolphi Messages postés 36 Date d'inscription mercredi 25 avril 2007 Statut Membre Dernière intervention 18 mai 2008 2
15 avril 2008 à 15:15
Oui je suis sur que le nombre est tout devant sans espace.
Je peut enlever la fonction instr() alors ?
0
Excuse pour l'attente, j'étais sorti.

Si tu es sur le le nombre est tout devant sans espaces, alors voici le programme sans la fonction instr().

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

#define LONG_BUF  256        /* longueur du buffer des fichiers */
  
char *lire_champs ();

int main()
{
   FILE *fp;
   char chaine1 [LONG_BUF], fich [LONG_BUF], mot [11], *chaine2;
   /*ouverture du fichier*/
   /*test si le fichier existe*/
   printf ("Fichier a explorer : ");
   gets (fich) ;
   if (strcmp (fich, "") == 0)      exit (0);
	     fp = fopen (fich, "r");
	     if (fp == NULL)
		{
		fclose (fp);
		fprintf (stderr,"\nERREUR D'OUVERTURE DU FICHIER %s\n", fich);
		getch();
		exit (1);
		}
   fclose(fp);
   /*boucle de recherche du nombre dans le fichier*/
   do
   {
     printf("\nEntrer le nombre recherche ou 0 pour quitter : ");
     scanf("%10s", mot);
     if (strcmp(mot,"0")!=0)
	     {
	     fp = fopen (fich, "r");
		while (fgets (chaine1, LONG_BUF, fp) != NULL)
			 {
            if (strcmp(lire_champs(chaine1,1),mot)==0)
			      {
 			       chaine2=&chaine1[strlen(mot)];
			       printf("%s\n",chaine2);
			       break;
			      }
			  }
		 if (strcmp (lire_champs (chaine1,1) ,mot) !=0 ) printf("non trouve\n");

		 fclose (fp);
	     }
   }
   while (strcmp(mot,"0")!=0);

return 0;
}


char *lire_champs (ligne, num_col)
char *ligne;
int num_col;
{
   char car;
   static char champ [LONG_BUF];
   int c, i, n, k;
   c = 0;  i = 0;   strcpy (champ, "");   n = strlen (ligne);  k = 0;
   if (n==0) return(champ);
   car = ' ';
   while (c < num_col  &&  i < n)       
   {
      while (car <= 32  &&  i < n)     car = ligne [i++];         
      if (i <= n)      c++;
      if (c == num_col)     break;
      while (car > 32  &&  i < n)      car =ligne [i++]; 
   }
   while (car > 32  &&  i < n)
   {
       champ [k++] = car;     car = ligne [i++]; 
   }
   if (c == num_col  &&  i >= n)        champ [k++] = car;
   champ [k] = '\0';
   return (champ);
}


Salut.
1