trouver un caractère dans une chaine?

trouver un caractère dans une chaine? - C - Programmation

Marsh Posté le 06-12-2004 à 01:09:29    

voilà, je m'étonne moi même de bloquer sur ce problème, je dois trop chercher la complication, enfin bref :
 
pour comparer 2 chaînes de caractères, pas de soucis, il y a la fonction strcmp() (même si les résultats retournés me sont encore un peu obscurs)
 
dans mon cas je voudrais pas comparer 2 chaînes, mais trouver si un caractère est présent dans une chaîne
 
dans l'idée, ça pourrait ressembler à ça (recherche d'un point d'interrogation) :
 

Code :
  1. for(i=0 ; i<longueur_de_ma_chaine ;i++)
  2. {
  3. if(chaine[i] == "?" )
  4.   return 1;
  5. }


 
à la compil j'ai le droit à un comparaison entre un pointeur et un entier :??::??:
 
je vois pas pourquoi? il faut que je compare avec le code ascii ou quelque chose comme ça?
 
merci

Reply

Marsh Posté le 06-12-2004 à 01:09:29   

Reply

Marsh Posté le 06-12-2004 à 01:16:41    

simple quote quand tu manipules un seul caractère donc '?'

Reply

Marsh Posté le 06-12-2004 à 01:17:14    

utilise la fonction strstr()


---------------
"I wonder if the internal negative pressure in self pumping toothpaste tubes is adjusted for different market altitudes." John Carmack
Reply

Marsh Posté le 06-12-2004 à 01:21:04    

strchr() plutôt.

Reply

Marsh Posté le 06-12-2004 à 01:22:36    

au passage je suis preneur d'une explication sur le fait que gcc renvoit une erreur de comparaison entre un pointeur et un entier dans ce cas ? why ?


Message édité par push le 06-12-2004 à 01:25:36
Reply

Marsh Posté le 06-12-2004 à 01:34:01    

simple quote :pfff: y a des fois je me demande si j'ai pas une maladie du cerveau qui me fait oublier les trucs évidents :pt1cable:
 
merci en tout cas!

Reply

Marsh Posté le 06-12-2004 à 01:46:32    

utilise quand même se qu'on t'on conseillé plus haut, genre  
 

Code :
  1. if(strchr(chaine, '?')) return 1;

Reply

Marsh Posté le 06-12-2004 à 01:55:40    

merci
 
en fait je me suis créé une fonction équivalente à strchr mais qui au lieu de me renvoyer le pointeur, me renvoi l'indice de position
 
petite question :  
il vaut mieux travailler avec les indices, genre tab[i] ou directement en modifiant les pointeurs genre tab=tab+i
 
parce que je trouve ça bcp plus lisible en []

Reply

Marsh Posté le 06-12-2004 à 02:26:26    

je suppose que tu as voulu dire utiliser tab[i] à la place de *(tab+i) ?
 
je suis pas une référence en C mais vu que les 2 écritures reviennent exactement à faire la même chose autant choisir la plus lisible.
 
ça vaut peut-être le coup que tu postes le code de ta fonction, d'autres pourront te corriger au besoin.

Reply

Marsh Posté le 06-12-2004 à 03:10:05    

voilà ma fonction équivalente à strchr :  
 

Code :
  1. int existe(char *str, char caract)
  2. {
  3. unsigned int i;
  4. for(i=0 ; i<(strlen(str)) ; i++)
  5. {
  6.   if (str[i] == caract)
  7.    return i;
  8. }
  9. return (-1);
  10. }


 
ça fonctionne bien, j'ai pu l'implementer dans mon code (en fait je dois faire des tests sur un fichier pour vérifier qu'il correspond au format recherché) et j'ai le résultat que j'attend
 
si vous voyez une amélioration ou une critique, je suis preneur!

Reply

Marsh Posté le 06-12-2004 à 03:10:05   

Reply

Marsh Posté le 06-12-2004 à 05:14:26    

Plusieurs remarques :

  • La declaration devrait plutôt être int existe(const char *str, char caract)
  • A cause du strlen, ta fonction parcourt la chaine entièrement deux fois dans le pire des cas, et une fois dans le meilleurs des cas.


Bref fais plutôt :

Code :
  1. int
  2. exist(const char *s, char c)
  3. {
  4.         unsigned int i;
  5.         for (i = 0; s[i] != '\0'; i++) {
  6.                 if (s[i] == c) {
  7.                         return i;
  8.                 }
  9.         }
  10.         return -1;
  11. }


Message édité par matafan le 06-12-2004 à 05:15:22
Reply

Marsh Posté le 06-12-2004 à 07:38:27    

ACYT a écrit :


il vaut mieux travailler avec les indices, genre tab[i] ou directement en modifiant les pointeurs genre tab=tab+i
 
parce que je trouve ça bcp plus lisible en []


 
Tu peux aussi écrire i[tab] c'est tout aussi correct (et tellement plus marrant)

Reply

Marsh Posté le 06-12-2004 à 19:16:46    

ACYT a écrit :

merci
 
en fait je me suis créé une fonction équivalente à strchr mais qui au lieu de me renvoyer le pointeur, me renvoi l'indice de position
 
petite question :  
il vaut mieux travailler avec les indices, genre tab[i] ou directement en modifiant les pointeurs genre tab=tab+i
 
parce que je trouve ça bcp plus lisible en []


De prime abord, "tab[i]" ou "*(tab + i)" ou "i[tab]" se passent exactement de la même manière. Le ptr "tab" est d'abord décalé de "i" puis le système va chercher ce qu'il y a à cet endroit.
Là où il peut y avoir lenteur, c'est quand tu demandes plusieurs fois "tab[i]" à ton pgm car le ptr est décalé à chaque fois.
A ce moment là, tu as tout intérêt à déclarer un second ptr "*pt", lui affecter "tab" et incrémenter "pt"
Ex1: Utilisation d'indice

Code :
  1. int exist(const char *s, char c)
  2. {
  3.         unsigned int i;
  4.         for (i = 0; s[i] != '\0'; i++) {
  5.                 if (s[i] == c) {
  6.                         return i;
  7.                 }
  8.         }
  9.         return -1;
  10. }


=> Dans cet exemple, tu demandes 2 fois s[i] donc il y a 2 fois l'opération "s + i" qui s'exécute
 
Ex2: Utilisation de pointeur

Code :
  1. int exist(const char *s, char c)
  2. {
  3.         char *pt;
  4.         unsigned int i;
  5.         for (pt=s, i=0; *pt != '\0'; pt++, i++) {
  6.                 if (*pt == c) {
  7.                         return i;
  8.                 }
  9.         }
  10.         return -1;
  11. }


=> Dans cet exemple, il n'y a aucun déréférencement pour aller chercher le contenu du i° caractère => balayage plus rapide !!!


Message édité par Sve@r le 06-12-2004 à 19:19:21
Reply

Marsh Posté le 06-12-2004 à 19:31:06    

Dans ton exemple tu as aussi une dereference.
 
Ta solution n'as pas d'adressage indexe. Par contre elle a deux aditions : une pour incrementer ptr, une pour incrementer i.
 
Ma solution a un adressage indexe. Mais ca ne represente finalement qu'une adition : n'importe quel compilateur sera capable de n'aller chercher s[i] qu'une seule fois (comme dans ton exemple d'ailleurs, pour tes deux *pt).
 
Donc attention aux optimisations qui n'en sont pas forcement ;) Par contre evidemment s'il n'avait pas voulu retourner l'indice du caractere, il aurait mieux valu incrementer ptr comme tu l'as fait.


Message édité par matafan le 06-12-2004 à 19:32:06
Reply

Marsh Posté le 06-12-2004 à 21:22:20    

matafan a écrit :

Par contre evidemment s'il n'avait pas voulu retourner l'indice du caractere, il aurait mieux valu incrementer ptr comme tu l'as fait.


Oui, j'ai été bloqué sur la fin de ce 2° exemple et j'ai été obligé de rajouter un "int i" pour avoir un compteur.
Peut-être peut-on remplacer ce "return i" final par un "return(pt - s)" ce qui supprime alors toute utilité de ce "int i" non ???

Reply

Marsh Posté le 06-12-2004 à 23:29:51    

est ce que ces optimisations sont vraiement nécessaires alors que mon programme sert juste à lire un fichier et à gérer un qcm? j'imagine que dans le cas de traitements lourds et répétitifs, ça trouve pleinement son intérêt mais là?

Reply

Marsh Posté le 06-12-2004 à 23:39:52    

autre petite question (j'ai fait une recherche rapide sous google et à vrai dire j'ai rien trouvé d'interessant là dessus) :
 
est-ce qu'en C il faut obligatoirement déclarer ses variables au début des fonctions, ou il est possible de le faire au milieu du code sans aucun problème?
 
genre si dans mon main(), j'ai des conditions élémentaires, et que seulement dans un cas je risque d'utiliser une variable, je peux la déclarer dans mon if?
 
j'avoue qu'en ce moment à apprendre le C, le Java, le C#, les scripts shell, le Php, l'UML, j'en passe, et pas des moindres, je m'y perd un peu!!!

Reply

Marsh Posté le 07-12-2004 à 02:00:16    

bon ben apparament c'est journée dodo le lundi :sleep:
 
je vais imiter tout le monde alors
 
:sleep:

Reply

Marsh Posté le 07-12-2004 à 02:31:17    

Taz ou d'autres te répondront mieux que moi mais, je ne sais plus quelle norme récente de C permet de déclarer des variables n'importe où. Par contre en C ansi, les déclarations sont forcément en début de bloc (mais pas forcément en début de fonction).
 
Donc pour répondre à ta question, oui, tu peux toujours déclarer tes variables au début de ton bloc if. Et leur portée est limité au bloc.

Reply

Marsh Posté le 07-12-2004 à 02:40:11    

ok c'est cool, sinon j'ai beaucoup de déclaration à déplacer et comme je suis un peu feignant :sarcastic:

Reply

Marsh Posté le 07-12-2004 à 10:38:34    

ACYT a écrit :

est ce que ces optimisations sont vraiement nécessaires alors que mon programme sert juste à lire un fichier et à gérer un qcm? j'imagine que dans le cas de traitements lourds et répétitifs, ça trouve pleinement son intérêt mais là?


Tout est relatif. Quand tu as posé la question s'il valait mieux utiliser les crochets plutôt qu'un pointeur tu parlais dans un cas général et on t'a répondu pareil. Ensuite, tout dépend évidemment de plusieurs critères dont
- le nombre d'appels à la fonction
- le nombre de fois où la fonction va utiliser un élément avec les crochets
etc etc etc
Tu peux faire en C des trucs absolument et totalement horribles (style tout écrire sur une seule ligne) et qui, cependant, fonctionneront. Chacun est libre. Il existe même un concours des plus horribles programmes en C.
 
Un très bon test pour s'autojuger est de relire ton code dans 3 mois. Là, tu seras mis au pied de ton propre mur...  :whistle:

Reply

Marsh Posté le 07-12-2004 à 22:11:02    

oui c'est sûr, on arrete pas de nous le rabacher... et j'avoue que j'ai toujours du mal à faire quelque chose de "propre"  
 
ça me fait penser que j'en suis à plus de 250 lignes de code et j'ai toujours pas de commentaire :whistle:
 
je le ferai à la fin :sarcastic: (pourquoi je ne me crois pas moi même? lol)

Reply

Marsh Posté le 08-12-2004 à 13:45:26    

ACYT a écrit :

je le ferai à la fin :sarcastic: (pourquoi je ne me crois pas moi même? lol)


Un commentaire c'est un truc inutile et dangereux. Le gars qui va relire notre code pourrait le comprendre et, pire, l'améliorer !!!
 
Astuce: Pour rendre notre programme absolument immuable, il y a un truc pas mal...
1) écrire le programme de façon classique, avec des include, etc
2) passer notre programme au préprocesseur. Il génère un fichier interprété ".i" contenant le ".c" mais sans les "include" ni les macro. Ces derniers ont été remplacé dans el ".i" par leur équivalent réel. Les include ont été inclus, les macro ont été remplacées par leur valeurs
3) renommer le ".i" en ".c". On aura un source vâchement béton, totalement illisible pour quiconque mais néanmoins parfaitement fonctionnel.
 
A tshaw...

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed