Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Implementation correcte de strchr ?

13 réponses
Avatar
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\n", e, (unsigned char)e);
printf("%d %d\n", 'é', (unsigned char)'é');
printf("1 %s\n", strchr("abcdéf", 'é'));
printf("2 %s\n", strchr("abcdéf", e));
printf("3 %s\n", mystrchr("abcdéf", 'é'));
printf("4 %s\n", mystrchr("abcdéf", e));
return 0;
}

3 réponses

1 2
Avatar
Samuel DEVULDER
Lucas Levrel a écrit :
Le 14 avril 2010, Samuel DEVULDER a écrit :

Xavier Roche a écrit :
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.



La manpage ne dit pas que l'int est converti en char immédiatement. Il



Il ne dit pas le contraire non plus. Il dirait même que c est
directement converti en char:
SYNOPSIS
#include <string.h>
char * strchr(const char *STRING, int C);

DESCRIPTION
This function finds the first occurence of C (converted to a
char) in the string pointed to by STRING (including the
terminating null character).


peut y avoir dans la fonction des tests d'erreur utilisant l'int, et si



Ca m'etonnerait car strchr() ne s'occupe que de chaines et de lettres.
Pas de notion d'un quelconque traitement sur les valeur de C qui
seraient des erreurs.

tout est OK l'int est changé en char pour être recherché dans la chaîne...



Tu veux parler d'un truc comme ca:

if(C!=(char)C) return null;

qui revient à considérer qu'un truc non représentable exactement avec un
char ne peut figurer dans la chaine et donc retourne null. Pourquoi pas.
Mais c'est bizzare quand même (sans compter qu'on a perdu le fait qu'on
avait atteint l'EOF dans le getchar() avant). A voir peut-être sur une
implémentation de référence.

sam.
Avatar
Samuel DEVULDER
Marc Espie a écrit :

Mais la vraie raison est ailleurs, c'est tout betement qu'il etait impossible
de faire autrement sans casser la compatibilite avec le C K&R.
Rappel: en C K&R, tu n'as pas de prototypes, et il y a un certain nombre
de promotions (je n'ai plus en tete le vocabulaire de la norme) qui sont
faites d'offices, tel que char -> int. Concretement, en C K&R, tu ne peux
pas passer de char a une fonction.



Ah ok. Les fameuses raisons historiques que je soupçonnais.

Du coup, mettre un char pour strchr, c'etait la rendre explicitement
incompatible avec le C classique.



C'est plus clair ainsi. Merci, c'est pile ce que je cherchais. Tu aurais
du écrire cela dès le départ plutôt que le très laconique EOF.

merci,

sam.
Avatar
Antoine Leca
Marc Espie écrivit :
Du coup, mettre un char pour strchr, c'etait la rendre explicitement
incompatible avec le C classique.



Et encore, c'est un des très rares cas où on aurait peut-être pu...
Car du fait de la conversion subséquente en char, le comportement est le
même, qu'il y ait le mécanisme ANSI de conversion vers char avant
l'appel, ou qu'il n'y soit pas et qu'on ait le mécanisme de promotion en
int, suivi d'une conversion en char.

Mais bon, par cohérence avec le reste des fonctions (où cela ne se passe
pas aussi « bien »), il est très compréhensible d'avoir adopté ce prototype.


Antoine
1 2