Langage C - Afficher une série de caracteres

Résolu
scolphi Messages postés 36 Date d'inscription   Statut Membre Dernière intervention   -  
scolphi Messages postés 36 Date d'inscription   Statut Membre Dernière intervention   -
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

amigo
 
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   Statut Membre Dernière intervention   2
 
Merci bcp ;)
0
amigo
 
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   Statut Membre Dernière intervention   2
 
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
amigo
 
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   Statut Membre Dernière intervention   2
 
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 33772 Date d'inscription   Statut Modérateur Dernière intervention   7 882
 
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   Statut Membre Dernière intervention   2
 
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   Statut Membre Dernière intervention   2
 
svp !
1
luffy duck
 
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   Statut Membre Dernière intervention   2
 
Je sais pas ce que c'est le batch.. Je doit le faire en C oui :/
0
amigo
 
OK, je refléchis un petit instant
1
amigo
 
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   Statut Membre Dernière intervention   2
 
Merci !!
Je vais essayer de comprendre maintenant. Je ne pensais pas que ça aurait été si compliqué..
0
amigo
 
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   Statut Membre Dernière intervention   2
 
Oui je suis sur que le nombre est tout devant sans espace.
Je peut enlever la fonction instr() alors ?
0
amigo
 
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