Info IUP2 Novembre 99

TP4 : chaines de chars, tableaux de tableaux tableaux dynamiques

0) j'explique un peu :

les spécificités des tableaux de cararctères, le \0, différence entre ' et ", scanf, gets, strlen, strcpy.

1) recherche d'une sous-chaîne

je donne :

#define LONGUEUR 80
typedef char texte[LONGUEUR];

void main(void)
 {
  texte ch,sch;
  printf("entrez votre chaine");
  scanf("%s",ch); //pas de & car déjà inclus dans &(ch[0])
  printf("entrez votre sous-chaine");
  scanf("%s",sch); 
  cherche(sch,ch);
 }

cherche est une fonction qui doit dire où et combien de fois on trouve la souschaine dans la chaine.

Exemple : chaine="FONCTION", souschaine="ON", on trouve deux fois la souschaine, enposition 1 et 6.

correction :

void cherche(texte souschaine,texte chaine)
{
int i,nb=0;
for(i=0;chaine[i];i++)
 {
  for(j=0;souchaine[j]&&chaine[i+j];j++) //tant que pas à la fin de l'1 des 2
        if(souschaine[j]!=chaine[i+j])break; //dès différence, sortie anticipée de la boucle
  if(!souschaine[j]) printf("%dième position : %d\n",++nb,i); //si arrivé au bout de souschaine, c'est trouvé
 }
}

2)introduction de plusieurs lignes de texte

on se limite à 20 lignes maxi, mais 1 seule sous-chaîne. Pour chaque ligne indiquer où et combien de fois, puis faire le total.

changements par rapport à la sol précédente :

dans main :

	texte ch;
devient :
	texte ch[20];

ainsi que

	printf("entrez votre chaine");
	scanf("%s",ch);
devient
	int nb=0,i=0,cpt=0;
	do
	 {
	  printf("entrez votre chaine, ligne vide pour finir");
	  gets(ch[nb]);
	  if(*(ch[nb])nb++; else break; //sortir de la boucle si chaîne vide
	 }
	while (nb<20);

ainsi que

	cherche(sch,ch);
devient
	for(i=0;i<nb;i++)
	{
	 printf("pour la ligne %d :\n",i+1);
	 cpt+=cherche(sch,ch[i]);
	}
	printf("sur toutes les lignes, trouvé en tout %d fois.\n",cpt);

cherche est également modifié : ne retourne plus void mais int, et return(nb); en dernière ligne

3)tableau dynamique :

je reste limité à 20 lignes, mais je ne veux occuper, pour chaque ligne, que la place nécessaire (je n'ai pas prévu d'allonger une ligne en cours de programme).

correction : rajouter la déclaration de type globale :

	typedef char textev[]; ou typedef char *textev;

(type texte à longueur variable, les deux écritures sont (presque) équivalentes)

dans main, je déclare :

texte tmp, sch;
textev ch[20];

gets(ch[nb]);
if(*(ch[nb])nb++; else break; 
devient
gets(tmp);
if(*tmp) 
 {
 ch[nb]=malloc((strlen(tmp)+1)*sizeof(char)); //prévoir le \0
 strcpy(ch[nb],tmp);
 nb++;
}
else break;

rien d'autre ne change.

Programme définitif :

#define LONGUEUR 80
typedef char texte[LONGUEUR];
typedef char *textev;

int cherche(textev souschaine,textev chaine) //texte allait aussi mais cherche marche pour toute longueur de chaîne, même >80
{
int i,nb=0;
for(i=0;chaine[i];i++)
 {
  for(j=0;souchaine[j]&&chaine[i+j];j++) //tant que pas à la fin de l'1 des 2
        if(souschaine[j]!=chaine[i+j])break; //dès différence, sortie anticipée de la boucle
  if(!souschaine[j]) printf("%dième position : %d\n",++nb,i); //si arrivé au bout de souschaine, c'est trouvé
 }
 return(nb);
}

 
void main(void)
{
texte tmp,sch;
textev ch[20];
int nb=0,i=0,cpt=0;
do
{
printf("entrez votre chaine, ligne vide pour finir");
gets(tmp);
if(*tmp) 
 {
 ch[nb]=malloc((strlen(tmp)+1)*sizeof(char)); //prévoir le \0
 strcpy(ch[nb],tmp);
 nb++;
}
else break;
}
while (nb<20);
printf("entrez votre sous-chaine");
scanf("%s",sch); 
for(i=0;i<nb;i++)
{
 printf("pour la ligne %d :\n",i+1);
 cpt+=cherche(sch,ch[i]);
}
printf("sur toutes les lignes, trouvé en tout %d fois.\n",cpt);
}

retour au sommaire des travaux pratiques d'informatique.


P. TRAU, ULP-IPST, 115/12/99