Aller au contenu

Recherche et tri de caractères en C


pacpis

Messages recommandés

Enfin un qui comprend mon problème, Je veux créer un tablleu contenant des mots, puis ensuite rechecher un mot dans ce tableau. suis -je clair à présent?

Donc si tu veux faire ca renseigne toi sur les tableaux en deux dimensions (char**) --> tu va créer un tableau qui va contenir tes strings :non:

Et sinon comme on ta dit auparavant pour comparer deux strings c'est la fonction strcmp du genre strcmp("Pablo","Pablo") va te retourner 0 (si je me trompe pas) sinon un nombre négatif si ta chaine s1 est plus petite que s2, ou un chiffre positif si ta chaine s1 est plus grande que s2. (enfin c'est un truc dans le genre --> donc tu test dans ton cas si la fonction strcmp retourne 0 sinon tu continue ton aventure dans ton char** pour continuer tes comparaisons).

A partir de maintenant regarde les cours de C sur le net pour comprendre comment manipuler les char** et la comparaison de string et poste du code si tu as des soucis la dessus :sm:

PS : Utilise fgets comme je l'ai dis pour récupérer une chaine de caractère taper au clavier dans une console.

Voila voila tu devrais pouvoir te débrouiller sinon poste du code :transpi:

Lien vers le commentaire
Partager sur d’autres sites

  • Réponses 69
  • Créé
  • Dernière réponse

sauf que en C/C++, on ne peut pas comparer 2 strings de cette facon :

tab[index_tab++] != mot

il faut passer par strcmp et/ou les variantes !!

Non.

Déjà ce sont des char et pas des strings.

Ensuite on n'utilise jamais strcpm qui est dangereux et expose à des stack overflox, mais strncp ou encore mieux (sous BSD) strlcmp.

Lien vers le commentaire
Partager sur d’autres sites

Ensuite on n'utilise jamais strcpm qui est dangereux et expose à des stack overflox, mais strncp ou encore mieux (sous BSD) strlcmp.

Je suis d'accord!! :incline:

Mais ça veux dire quoi? :eeek2::-D

C'est dangereux en quoi de l'utiliser pour une simple comparaison dans des fichiers ou des matrices?

Lien vers le commentaire
Partager sur d’autres sites

C'est la différence entre un soft dev pour windows et un soft dev pour OpenBSD (troll).

Le principe de base et de ne rien truster.

Ton fichier il vient d'où ? Ta matrice elle est remplie comment ?

Il est de la responsabilité du programme de tester TOUT les input. Que ce soit une saisie au clavier, un paquet réseau (même l'ICMP (célèbre ping of death), DNS (dns poisoned) etc.), un fichier, une interuption, un flux, un pipe, un signal, un message, ...

Maintenant chacun fait ce qu'il veux hein. Ce n'est pas une obligation. Et puis ça se saurait si il n'y avait pas 80% de code crade dans la nature.

Lien vers le commentaire
Partager sur d’autres sites

Je suis entrain de chercher depuis un long moment mais j'ai les memes erreurs de segmentation qui reviennent :reflechis:

Je ne sais meme pas d'ou vient mon erreur: le code est ceci:

#include<stdio.h>
#include<stdlib.h>
#define nbr_mot 5


main(void)
{
/* DECLARATION DES VARIABLES */
 int  i;
 char tab[nbr_mot], mot;
 int trouve=0, index_tab=1;

/* CORPS DU PROGRAMME */
 /*Remplissage du tableau*/
printf("Saisir le nombre de mots du tableau : ");
scanf("%d", nbr_mot);
printf("Saisir les mots du tableau: ");
 for(i==1; i==nbr_mot; i++)
 gets(tab);

/*Recherche d'un mot dans un tableau*/
printf("\n Saisir le mot à rechercher dans le tableau :  ");
scanf("%s", mot);
while (strcmp(tab[index_tab++], mot) && index_tab<nbr_mot);
{
 if(tab[index_tab]==mot)
  trouve=1;
  else {
	 index_tab++; }
}
if(trouve=1)
  printf("Le mot cherché est à la ligne %d", index_tab);

}

Lien vers le commentaire
Partager sur d’autres sites

Le problème des erreurs de segmentation c'est que c'est difficile de savoir ou ca plante.

En général j'utilise gdb pour en savoir plus mais tu dois pas trop connaitre. Donc poste ton code final que l'on puisse le prendre et compiler de nous même pour voir où ca plante.

Mais sinon ton programme encore une fois me semble t'il les autres pourrait le confirmer ne fera pas ce que tu demande --> Mettre des mots différent dans un tableau et déterminer si le mot tapé par l'utilisateur existe. Première piste --> Tu utilise un tableau a une dimension donc logiquement tu écrases sans arrêt ce que tu as tapé precedement.

Lien vers le commentaire
Partager sur d’autres sites

Je suis un peu confus avec ce que tu viens de me dire, voila mon code final:

#include<stdio.h>
#include<stdlib.h>
#define nbr_mot 5


main(void)
{
/* DECLARATION DES VARIABLES */
 int  i;
 char tab[nbr_mot], mot;
 int trouve=0, index_tab=1;

/* CORPS DU PROGRAMME */
 /*Remplissage du tableau*/
printf("Saisir le nombre de mots du tableau : ");
scanf("%d", nbr_mot);
printf("Saisir les mots du tableau: ");
 for(i==1; i==nbr_mot; i++)
 fgets(tab, 1024, stdin);

/*Recherche d'un mot dans un tableau*/
ptr=&tab[nbr_mot];
printf("\n Saisir le mot à rechercher dans le tableau :  ");
scanf("%s", mot);
while (strcmp(tab[index_tab++], mot) && index_tab<nbr_mot);
{
 if(tab[index_tab]==mot)
  trouve=1;
  else {
	 index_tab++; }
}
if(trouve==1)
  printf("Le mot cherché est à la ligne %d", index_tab);

}

Lien vers le commentaire
Partager sur d’autres sites

Disons que tu déclare bien ton tableau comme ca : char tab[nb_mot], en fait la tu déclare un tableau qui va contenir des caractères dans ces cases avec une nombre de case correspondant a nb_mot. Donc dans ce cas la ton tableau ne stockera qu'une seul chaine de caractère --> En plus pour que cela soit considéré comme une chaîne de caractère il faut mettre \0 à la fin.

Enfin je sais pas trop comment expliqué lol j'ai jamais été très bon pour ca :eeek2:

Lien vers le commentaire
Partager sur d’autres sites

bon, on va la refaire moins stressé ;)

une chaine de caractère, c'est un ensemble de caractères les uns à côté des autres. Donc on va se dire que c'est un tableau de caractères.

On peut déclarer une chaîne de caractères comme ceci :

char chaine[10]; /* une chaine de 9 caractères */

Cette chaine ne fait que 9 caractères car la dernière case du tableau doit être un zero (c'est comme ça qu'on sait que la chaine est terminée).

Dans ce cas, chaine représente l'adresse de la première case du tableau. chaine[0] représente le contenu de la première case. (chaine + 1) représente l'adresse de la deuxième case du tableau, et chaine[2] le contenu de la deuxième case, (chaine + 2) la troisème case et chaine[2] le contenu de la troisième case, etc...

Donc ce qui nous intéresse, c'est l'adresse de la première case, car à partir de cela, on peut reconstruire toute la chaine (il suffit de continuer à lire la case d'après jusqu'à ce que son contenu vaille 0).

On va donc se contenter de conserver l'adresse de la première case de notre chaine. pour ça, il nous faut une variable qui contient une adresse : un pointeur.

 char * chaine; /*pointeur vers un caractère */

puis, on va faire pointer ce pointeur vers l'adresse de la première case de notre chaine. Pour cela, on va allouer l'espace pour le tableau avec malloc() :

chaine = (char*) malloc(10*sizeof(char)); /* allocation d'un tableau de 9 caractères */ 

pour remplir notre chaine avec l'entrée standard, il suffit d'appler fgets :

fgets(chaine, 10, stdin); /* lecture de 10 char sur l'entrée standard */

voilà pour la base. Ce que tu veux faire, c'est avoir un tableau de chaine de caractères. Il nous faut donc un tableau donc chaque case contient de quoi retrouver la chaine associée. Or on a dit que pour repérer une chaine, l'adresse du premier caractère de la chaine suffisait, on va donc faire un tableau d'adresses de caractère:

char* * chaines; /* un pointeur vers des pointeurs de caractères */

maintenant, il faut que notre pointeur pointe vers la première case du tableau d'adresses de chaines de caractères. En supposant qu'on veuille un tableau de 10 chaines de caractères, cela donne :

 chaines = (char**) malloc(10*sizeof(char*)); /*allocation d'un tableau de 10 (char*) */

grâce à cela, chaines[0] est l'adresse du premier caractère de la première chaine, chaines[1] l'adresse du premier caractère de la seconde chaine, chaines[2] l'adresse du premier caractère de la troisième cahines, etc, etc...

Sauf que ces chaines (ces tableaux) n'existe pas encore, il faut donc les allouer :

int i;
for(i = 0; i < 10; i++)
  chaines[i] = (char*) malloc(20*sizeof(char)); /*allocation d'une chaine de 19 caractères + 0 */

maintenant, si tu veux remplir chacune de ces chaines, il suffit de faire une boucle de fgets :

for(i = 0; i < 10; i++)
fgets(chaines, 19, stdin); /* remplit chaque tableau avec au plus 19 caractère lut sur l'entrée standard */

voilà, voilà, maintenant, tu as toutes les cartes en main.

Un petit conseil, fixe toutes les tailles dans ton programme avec des #define, comme la taille de tes chaines de caractères:

#define TAILLE_CHAINE 20
/* les chaines feront 19 caractères */

char * chaine;
chaine = (char*) malloc(TAILLE_CHAINE * sizeof(char));

Autre conseil, assure toi systématiquement que tes chaine se termine bien par 0 en forçant cette valeur à chaque fois que tu remplis :

fgets(chaine, TAILLE_CHAINE-1, stdin);
chaine[TAILLE_CHAINE - 1] = 0;

bon courage :yes:

Lien vers le commentaire
Partager sur d’autres sites

en fait la fin d'une chaîne est bien 0 (valeur entière zero) qui se note sous la forme d'un caractère '\0' pour le différencier de '0' qui est le caractère zero et qui prend la valeur entière 48.

C'est le code ascii.

voilà, voilà :youhou:

Oki mais vallait peut être mieux le préciser pour qu'il comprenne le truc --> parce que je pense que si tu crée une chaine de caractère a la mano faut rajouter à la fin '\0' --> Comme tu l'explique j'aurais rajouté directement 0. A part si ca fonctionne quand même comme ca mais ca m'etonne enfin j'ai jamais testé :byebye:

Lien vers le commentaire
Partager sur d’autres sites

Ta variable trouve ne sert à rien.
oui, mais non

s'il veut afficher le resultat apres le while, il devra refaire un test de comparaison sur les 2 chaines de caracteres (couteux en temps surtout sur des chars)

Il suffit de comparer index_tab et nbr_mot et de mettre un break dans le while, ce qui évitera des comparaisons justement. Sans compter que j'ai un doute sur le fait que index_tab est incrémenté deux fois.

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.


×
×
  • Créer...