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

Probleme avec scanf

118 réponses
Avatar
Bakounine
bonjour

je suis en train de faire un petit programme client et serveur qui echange
des messages. Dans cetains messages il y a deux valeur separer par des deux
points.

ex:

valeurun:valeurdeux

j'aimerais savoir si sscanf permet de gerer le separateur : ou faut il
utiliser une autre fonction? j'ai utilise sscanf("%s:%s", var1, var2); mais
ca ne marche pas.

Merci d'avance pour votre reponse.

10 réponses

8 9 10 11 12
Avatar
Emmanuel Delahaye
Antoine Leca wrote on 29/04/05 :
En <news:,Yves ROMAN va escriure:
Parce qu'il sait que sizeof("??/??/????") == 6


Ah oui !!!

Bravo à Oil de Lynx. Applaudissement nourri (?) de la foule en délire (??)

(Au début j'avais pensé que ça valait sizeof(char *) : je me fais
avoir à chaque fois, alors j'ai fait le test...)


En pensant à mettre -trigraphs (ou à passer par le filtre TRIGRAPH de
Borland), ce que manifestement ED a dû oublier...


Oui, complètement.

Cela étant, alors que gcc 3.2 -W est silencieux sur le sujet (-Wall
babille), gcc 3.4.2 signale le potentiel piège. Curieux (et bonne chose, en
fait).


Voilà qui va se terminer par une petite révision de mon code. Plus
jamais de '??' sans réfléchir intensément.

Et puis je vais mettre -trigraph dans mes makefiles.

Merci à tous. On en en apprend tout les jours et c'est tant mieux.

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

I once asked an expert COBOL programmer, how to
declare local variables in COBOL, the reply was:
"what is a local variable?"


Avatar
Yves ROMAN

Yves ROMAN wrote:

Yves ROMAN wrote:








Par contre, sous Visual, en sortie préprocesseur (option /EP), je ne
vois pas le caractère de remplacement des trigraphes quand ceux ci
sont embarqués dans des chaînes.

#include <stdio.h>

int main(void)
??<
char tab??()??;
printf("taille : %lun", (unsigned long)sizeof("??/??/??/??/????")
);
return 0;
??>

Je vois bien les { } [ ] manquants, mais la chaine donnée à
l'opérateur sizeof reste la même, j'aurais espérer que ce soit
"\????", et je ne sasi pas si c'est normal. Qu'en est-il avec
d'autres compilos ?



Avec SParcCompiler 5, le préprocesseur remplace tous les trigraphes (dans le
code et les chaines de caracteres), on obtient donc bien "\????" avant la
compilation, ce qui donne bien une taille de 7





Avatar
Antoine Leca
En <news:, Emmanuel Delahaye
va escriure:
Voilà qui va se terminer par une petite révision de mon code. Plus
jamais de '^ sans réfléchir intensément.


Pardon ? Que veut dire ce souriard-là ?

:??')



Et puis je vais mettre -trigraph dans mes makefiles.


-trigraphs


Antoine

Avatar
Emmanuel Delahaye
Charlie Gordon wrote on 29/04/05 :
#define MAX_DATE_SIZE sizeof("??/??/????")


Tu m'as foutu la trouille! J'ai cru que j'avais écrit ça dans mon code!

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"There are 10 types of people in the world today;
those that understand binary, and those that dont."

Avatar
Charlie Gordon
"Emmanuel Delahaye" wrote in message
news:
Charlie Gordon wrote on 29/04/05 :
#define MAX_DATE_SIZE sizeof("??/??/????")


Tu m'as foutu la trouille! J'ai cru que j'avais écrit ça dans mon code!


Non, tu utilises entre autres ##/##/#### et ??? ??? ??? mais ça m'a rappelé mon
test de la mort qui tue que bien peu de candidats developpeurs savent démêler,
en particulier avec VC++. gcc est moins piégeux avec ces trigraphes aussi
inutiles que les digraphes que les experts du C99 ont cru bon de rajouter :-((.

En tous cas, l'investigation d'Antoine sur VC++ m'a fait rouler par terre ;-)

Bon week-end à tous.

Chqrlie.


Avatar
Charlie Gordon
"Antoine Leca" wrote in message
news:d4t45h$k6b$
En <news:d4svcg$pda$, Charlie Gordon va escriure:

#define MAX_DATE_SIZE sizeof("??/??/????")
char buf[MAX_DATE_SIZE];
sprintf(buf, "%02u/%02u/%04u",
,ftimep.ft_day
,ftimep.ft_month
,ftimep.ft_year + 1980);


Si tu vas par là...

sprintf(buf, "%02u/%02u/%04u",
ftimep.ft_day + 0u,
ftimep.ft_month + 0u,
ftimep.ft_year + 1980u);


Non, je ne vois pas ce que cela apporte.

Mais il y a des problèmes plus graves dans ce code :


L'utilisation d'une structure étiquettée ftime avec un identificateur ftimep
qui suggère un pointeur ?


Oui, 3 points pour Antoine, c'est vraiment immonde d'appeler une structure comme
ça !

(En maintenance cela vaut 3 points en moins: 1 point pour le non-respect des
conventions qui disent le contraire « Ne cachez pas vos pointeurs », plus 2
points rajoutés par le mainteneur qui s'est fait prendre et a changé le .
en -> en pensant qu'il avait affaire à un pointeur ;-)).


Tout à fait d'accord !

Ou alors tu penses au sizeof «juste limite» ?


Oui, 1 point supplémentaire, mais c'est encore un peu plus tordu que cela...

Chqrlie.

Targeur Fou : 1 point
Antoine Leca : 4 points


Avatar
Emmanuel Delahaye
Antoine Leca wrote on 29/04/05 :
En <news:, Emmanuel Delahaye
va escriure:
Voilà qui va se terminer par une petite révision de mon code. Plus
jamais de '^ sans réfléchir intensément.


Pardon ? Que veut dire ce souriard-là ?

:??')

Et puis je vais mettre -trigraph dans mes makefiles.


-trigraphs


Ok, merci. Au fait -Wtrigraphs, c'est interessant ?

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

.sig under repair


Avatar
Charlie Gordon
"Antoine Leca" wrote in message
news:d4t18f$9vd$
En <news:,
Targeur fou va escriure:
Charlie Gordon wrote:
PS: pour les courageux qui lisent mes posts jusqu'au bout,



J'avoue que je n'étais pas allé jusque là. Donc merci Régis pour avoir
ressorti la prose de Charles ;-).


voici un petit test d'acuité visuelle :
Pour quelles raisons ED ne doit-il pas utiliser le code suivant pour
sa conversion de dates :


C'est pas le sizeof qui est correct..., C'est peut être au niveau du
format dans sprintf, les champs de la structure ftime étant des champs
de bits unsigned, c'est un format "%02u/%02u/%04u" qu'il faudrait,
j'ai bon ?


En supposant que la structure ftime est bien celle de MS-DOS (5 bits, 4
bits, 7 bits), tous inférieurs à 16, donc les valeurs seront promues en int
et non pas en unsigned (à moins d'utiliser un compilateur pré-ANSI, mais
alors il n'y a plus de souci entre %d et %u pour des valeurs positives). Et
bien sûr l'addition avec la constante entière 1980 < 32640 ne change rien à
cela. Donc non, c'est bien %d qu'il faut utiliser; ou alors tu programmes
défensivement et tu ajoutes 0u ou 1980u à chaque membre.


Non, le fait que les champs soient unsigned fait qu'un compilateur comme gcc qui
vérifie la cohérence du format de printf avec le type des arguments passés
(-Wall bien sur) va produire un avertissement si on utilise pas %u. Rajouter
des 0u ou 1980u n'est pas nécessaire.

Par ailleurs, rien ne dit que la structure est correctement remplie par la
fonction de librairie, en particulier si l'horloge système délire, donc il est
préférable de prévoir tous les cas possibles et donc de dimensionner le buffer
de facon plus large.

Je dirais que les valeurs 0 pour ft_day et ft_month ne signifient pas le
jour ou le mois numéro 0 :^), mais plutôt l'absence de l'information; à ce
titre il faudrait les traiter à part, à mon sens.


Sans doute, mais pas de point pour ça...

Ou alors c'est le syndrome 9/11 = 8601...


Peux-tu développer ce point ?

Chqrlie.



Avatar
Charlie Gordon
"Yves ROMAN" wrote in message
news:


PS: pour les courageux qui lisent mes posts jusqu'au bout, voici un petit
test


d'acuité visuelle :
Pour quelles raisons ED ne doit-il pas utiliser le code suivant pour sa
conversion de dates :

#define MAX_DATE_SIZE sizeof("??/??/????")

char buf[MAX_DATE_SIZE];
sprintf(buf, "%02d/%02d/%04d",
,ftimep.ft_day
,ftimep.ft_month
,ftimep.ft_year + 1980);


Parce qu'il sait que sizeof("??/??/????") == 6
et il utilisera plutot sizeof("00/00/0000")

"??/??/????" -> ????


YES !

Sans doute une histoire de trigrammes, mais je ne les connais pas du tout ....
Est-ce que ca veut dire que ??/??/ -> ?


Eh oui ! les trigraphes ont encore frappé !

(Au début j'avais pensé que ça valait sizeof(char *) : je me fais avoir à
chaque

fois, alors j'ai fait le test...)


Comme quoi il faut toujours faire le test, pour de bonnes comme de mauvaises
raisons ;-)

5 points pour Yves ROMAN.

Chqrlie.

Targeur Fou : 1
Antoine Leca : 4
Yves Roman : 5


Avatar
Charlie Gordon
"Antoine Leca" wrote in message
news:d4tko7$jka$
En <news:,
Régis fou va escriure:
Par contre, sous Visual, en sortie préprocesseur (option /EP), je ne
vois pas le caractère de remplacement des trigraphes quand ceux ci
sont embarqués dans des chaînes.


C'est encore plus drôle que cela.

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.40904 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
char buf[sizeof("????")];
printf("taille : %lun", (unsigned long)sizeof("??/??/??/??/????"));


L'un est remplacé, l'autre pas ???
Autrement dit, ils doivent avoir deux logique de lecture des trigraphes...


À mon avis il doit y avoir des moyens de les coincer }:->

Mais en fait j'ai été trop subtil :^)

#define FAUX ???/
?/??
#define xs(x) #x
#define str(x) xs(x)

printf("taille : %lun", (unsigned long) sizeof str(FAUX) );

donne

printf("taille : %lun", (unsigned long) sizeof "??" );

C'est-à-dire qu'il substitue le faux trigraphe à l'intérieur de FAUX
(normalement phase 1), *après* avoir opérer la réunion de ligne du +fin de
ligne (normalement phase 2), donc tout faux. Si quelqu'un peut reporter des
bogues contre VC++ (j'ai testé la dernière bêta dispo), faites chauffer la
colle!

On dirait que le bogue existe depuis pas mal de temps. MS C/C++ 7.0, la
première version (92) qui semble savoir traiter les trigraphes, a déjà les
mêmes problèmes.
C 6.0a (91) a des problèmes pour démeler mon horreur, mais pour ton exemple
donne déjà le même résultat que celui de la version 14 du compilo (buf avec
la macro OK, sizeof du littéral pas de remplacement).


Bon, c'est pas tout cela, j'ai autre chose à faire que de corriger le code
de 1991 de MS pour traiter les trigraphes ;-)


Là, je suis scié !
2 points pour Regis pour avoir levé ce lièvre, et 2 points de plus pour Antoine
pour sa trouvaille proprement délirante.

Palmarès :

Antoine Leca : 6 points
Yves Roman : 5 points
Regis : 2 points
Targeur Fou : 1 point

--
Chqrlie.


8 9 10 11 12