GNT sans publicité, site mobile, fonctionnalitées exclusives...

Implementation correcte de strchr ?

Le
candide
Quel est votre avis sur cette implémentation de strchr ?


Le code :


/* Source à encoder en ISO-8859-1. */

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

char *mystrchr(const char *s, int c)
{
while ((unsigned char)*s != (unsigned char)c) {
if (*s == '\0')
return NULL;
++s;
}
return (char*)s;
}


int main(void)
{
const int e = getchar();
printf("%d %d", e, (unsigned char)e);
printf("%d %d", 'é', (unsigned char)'é');
printf("1 %s", strchr("abcdéf", 'é'));
printf("2 %s", strchr("abcdéf", e));
printf("3 %s", mystrchr("abcdéf", 'é'));
printf("4 %s", mystrchr("abcdéf", e));
return 0;
}
Lire les 13 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Samuel DEVULDER
Le #21550901
candide a écrit :
Quel est votre avis sur cette implémentation de strchr ?


Le code :


/* Source à encoder en ISO-8859-1. */

#include #include
char *mystrchr(const char *s, int c)


^^^
Pourquoi int? "char" irait, non? Ca serait cohérent avec la déclaration
de "s".

C'est pas parce que strchr veut un int qu'on est obligé de faire pareil,
surtout que le manpage dit d'ailleurs que le c est converti en char en
interne (sans précision sur le signe de char).

Si quelqu'un connait la raison sur le choix du int pour c, je suis
intéressé. J'ai rien trouvé dans les manpages là dessus.

{
while ((unsigned char)*s != (unsigned char)c) {


^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
A quoi servent les deux cast en unsigned? On peut pas faire avec un cast
à (char) sur c directement? (pour que *s et (char)c aient tous les deux
le même type).

sam.
espie
Le #21551241
In article Samuel DEVULDER wrote:
candide a écrit :
Quel est votre avis sur cette implémentation de strchr ?


Le code :


/* Source à encoder en ISO-8859-1. */

#include #include
char *mystrchr(const char *s, int c)


^^^
Pourquoi int? "char" irait, non? Ca serait cohérent avec la déclaration
de "s".

C'est pas parce que strchr veut un int qu'on est obligé de faire pareil,
surtout que le manpage dit d'ailleurs que le c est converti en char en
interne (sans précision sur le signe de char).

Si quelqu'un connait la raison sur le choix du int pour c, je suis
intéressé. J'ai rien trouvé dans les manpages là dessus.



EOF
Samuel DEVULDER
Le #21551881
Marc Espie a écrit :

Si quelqu'un connait la raison sur le choix du int pour c, je suis
intéressé. J'ai rien trouvé dans les manpages là dessus.



EOF



Heu? Mais encore? Si j'osais (arthur :-) ) je dirais que c'est du grand
n'importe quoi. EOF c'est pour les flux, et là on est dans le monde des
chaines. Il n'y a aucun rapport entre les deux.

Il doit y avoir une autre raison. Sans compter que si on passe EOF dans
c, on se retrouve à faire (char)EOF ou (unsigned char)EOF, ce qui est
d'une bêtise sans nom.

sam (EOT)
Xavier Roche
Le #21551981
Samuel DEVULDER a écrit :
Heu? Mais encore? Si j'osais (arthur :-) ) je dirais que c'est du grand
n'importe quoi. EOF c'est pour les flux, et là on est dans le monde des
chaines. Il n'y a aucun rapport entre les deux.



Je suppose que dans la mesure où getc() renvoi un int (pour permettre de
renvoyer des codes d'erreurs), putc() prend également un int.

Cela peut potentiellement permettre de faire en sorte que
putchar(getc()) renvoi une erreur si getc() a lui même renvoyé une erreur.

Par extension, tout ce qui manipule des char utilisent des int (je vois
aussi memset(), dans le même genre) - enfin c'est une explication
possible ; ie. strchr(str, getchar()) ne nécessite pas de cast.
Samuel DEVULDER
Le #21552501
Xavier Roche a écrit :
Samuel DEVULDER a écrit :
Heu? Mais encore? Si j'osais (arthur :-) ) je dirais que c'est du
grand n'importe quoi. EOF c'est pour les flux, et là on est dans le
monde des chaines. Il n'y a aucun rapport entre les deux.



Je suppose que dans la mesure où getc() renvoi un int (pour permettre de
renvoyer des codes d'erreurs), putc() prend également un int.



Oui.. que les fonction d'i/o utilisent EOF je n'ai pas de soucis, mais
c'est voir la présence de EOF dans une routine de manip de chaine qui
laisse perplexe.

Cela peut potentiellement permettre de faire en sorte que
putchar(getc()) renvoi une erreur si getc() a lui même renvoyé une erreur.



Par extension, tout ce qui manipule des char utilisent des int (je vois
aussi memset(), dans le même genre) - enfin c'est une explication
possible ; ie. strchr(str, getchar()) ne nécessite pas de cast.



Oui.. mais c'est une curieuse façon de coder. D'une part on se demande
l'intérêt d'éviter un cast à cet endroit là et de le repousser dans la
librairie. Et d'autre part la fin de fichier est silencieusement ignorée
et là c'est carrément moche. Il faut espérer que l'utilisateur fasse
appel à feof() avant de travailler avec ce que retourne strchr().

J'imagine assez qu'il y a des raisons historiques finalement là dessous.
Peut être datant de l'époque où l'on aimait pas le code machine produit
par les compilos quand il fallait convertir un int en char et qu'on
préférait gérer cela à sa sauce efficacement en asm dans les
bibliothèques standard.

sam.
Publicité
Suivre les réponses
Poster une réponse
Anonyme