OVH Cloud OVH Cloud

printf et scanf

102 réponses
Avatar
Pascal
Bonjour,

J'ai des pb bizarres : dans une fonction j'ai besoin que l'utilisateur
me donne plusieurs infos, je fais donc des printf("question") et des scanf.

Sur les 3 premieres questions, ca marche bien, sur les 2 dernières, le
programme les affiche, mais le scanf ne semble pas marcher. Pourtant le
scanf recup sur les 5 fois un char *. C'est un bug? D'ailleurs si je ne
mets pas de \n sur le printf, parfois c'est encore pire...
voici un ex :
char *nom;
printf("nom\n");
scanf("%s", nom);
etc .. prenom, adress, tel, mail...

Parfois le scanf est comme sauté. Dans une autre fonction, je fais la
meme chose : une question, une reponse. Il m'affiche bien la question,
mais le scanf comme s'il était inactif, le programme ne me laisse pas
répondre, et passe à l'instruction suivante...

10 réponses

7 8 9 10 11
Avatar
Laurent Deniau
Jean-Marc Bourguet wrote:
Laurent Deniau writes:


Quel est l'interet?



- Avoir un moyen portable de dire que c'est volontaire que le parametre
ne soit pas utilise. Ca evite les /*LINT:UNUSED*/ et autres pragmas.


je prefere:

void format(void *unused)
{
(void)unused;
}

au moins je suis sur que ce n'est pas un oubli/erreur.

- Supprimer une difference mineure avec le C++.


certe.

a+, ld.


Avatar
Laurent Deniau
Charlie Gordon wrote:
"Laurent Deniau" wrote in message
news:cncg88$4su$

Charlie Gordon wrote:

"Emmanuel Delahaye" wrote in message
news:


James Kanze wrote on 13/11/04 :


Je te donne une implémentation qui remplit toutes tes exigeances :

void
format( void* )
{
}

C'est simple, flexible, robuste et on ne peut plus rapide.


Ne compile pas. Il manque le nom du paramètre.



Dommage, ne pas nommer le paramètre est pourtant une façon simple de dire



qu'il

n'est pas utilisé !
Il semblerait que cette proposition n'ait pas été retenue pour être intégrée



au

standard.
Qui en sait plus à ce sujet ?


Quel est l'interet?



Le prototype de la fonction peut etre fixé par des contraintes externes à
celle-ci,


On parle bien de definition de fonction et pas de declaration de
fonction? (ce dernier cas ne me pose pas de probleme).

On peut par exemple faire emettre un warning par le compilo quand une variable
est declaree mais pas utilisee.


Tu veux dire un parametre?

Dans le cas des parametres de fonction, cela peut etre voulu.
Disposer d'une methode portable pour preciser cela n'est pas inutile.


void format(void *unused)
{
(void)unused; // a enlever si on veut un warning.
}

Cela évite la tentation des extension sordides du style #pragma unused et
autres.


Qui devrait faire quoi?

On a bien des unnamed bitfields

Qu'en est-il des champs de structure non nommés, des unions transparentes ?


Ce n'est toujours pas possible a mon grand regret.

a+, ld.





Avatar
Charlie Gordon
"Laurent Deniau" wrote in message
news:cncpf8$pnh$
Jean-Marc Bourguet wrote:
Laurent Deniau writes:


Quel est l'interet?



- Avoir un moyen portable de dire que c'est volontaire que le parametre
ne soit pas utilise. Ca evite les /*LINT:UNUSED*/ et autres pragmas.


je prefere:

void format(void *unused)
{
(void)unused;
}

au moins je suis sur que ce n'est pas un oubli/erreur.


C'est trop immonde.
Si on a plus d'un parametre, on se retrouve avec des unused1, unused2...
Certains compilateurs vont même jusqu'à trouver la ligne (void)unused; suspecte,
ou considèrent que cela ne suffit pas a supprimer le doute. Je ne parle pas des
alternatives encore pires du genre : unused = unused;

Je suis bien content de pouvoir supprimer specifiquement le warning pour les
arguments non utilisés, dont je ne souvient pas qu'il m'ait jamais montré un bug
dans les environnements ou je ne pouvais pas le controler independamment des
variables auto ou static.

Chqrlie.



Avatar
Antoine Leca
En cncq86$5bl$, Charlie Gordon va escriure:

Je suis bien content de pouvoir supprimer specifiquement le warning
pour les arguments non utilisés,


Cet avertissement date du temps (pas forcément révolu) où les passages de
paramètres coutaient cher. Je ne pense pas que ce soit forcément indicateur
de bogue, plutôt de programmation inefficace.

Le code jamais exécuté (genre à la suite de if(0), après return ou exit())
rentre dans la même catégorie, sauf que ce dernier avertissement peut
parfois servir à démasquer des bogues avec des comparaisons < 0 de quantités
non signées.


Antoine

Avatar
Laurent Deniau
Charlie Gordon wrote:
"Laurent Deniau" wrote in message
news:cncpf8$pnh$

Jean-Marc Bourguet wrote:

Laurent Deniau writes:



Quel est l'interet?



- Avoir un moyen portable de dire que c'est volontaire que le parametre
ne soit pas utilise. Ca evite les /*LINT:UNUSED*/ et autres pragmas.


je prefere:

void format(void *unused)
{
(void)unused;
}

au moins je suis sur que ce n'est pas un oubli/erreur.



C'est trop immonde.


question de gout:

extern void *fmt; // dans un header inclu

void format (void* /* oubli du nom fmt */)
{
use(fmt); // erreur de codage, devrait utiliser le parametre fmt
}

Si on a plus d'un parametre, on se retrouve avec des unused1, unused2...


voui, et alors?
voir un (void) me confirme que ce n'est pas un oubli mais bien intensionnel.

Certains compilateurs vont même jusqu'à trouver la ligne (void)unused; suspecte,


je ne vois pas pourquoi. je fais ca tres souvent, notament pour eliminer
une branche de ?:

ou considèrent que cela ne suffit pas a supprimer le doute. Je ne parle pas des


quel doute?

alternatives encore pires du genre : unused = unused;


le probleme c'est que je dois souvent negliger un parametre qui n'est
pas le dernier:

void format(void *self, void *arg)
{
(void)self;
use(arg);
}

Comment est-ce que tu fais avec les parametres non-nommes?

note que self reste indispensable comme parametre, mais il est inutile
dans le corps de la fonction.

Je suis bien content de pouvoir supprimer specifiquement le warning pour les
arguments non utilisés, dont je ne souvient pas qu'il m'ait jamais montré un bug
dans les environnements ou je ne pouvais pas le controler independamment des
variables auto ou static.


a+, ld.




Avatar
Jean-Marc Bourguet
Laurent Deniau writes:

void format(void *self, void *arg)
{
(void)self;
use(arg);
}

Comment est-ce que tu fais avec les parametres non-nommes?


void format(void*, void* arg)
{
use(arg);
}

Quel est le probleme?

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Emmanuel Delahaye
Charlie Gordon wrote on 16/11/04 :
Cela évite la tentation des extension sordides du style #pragma unused et
autres.



(void) parametre;

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

"C is a sharp tool"

Avatar
Laurent Deniau
Jean-Marc Bourguet wrote:
Laurent Deniau writes:


void format(void *self, void *arg)
{
(void)self;
use(arg);
}

Comment est-ce que tu fais avec les parametres non-nommes?



void format(void*, void* arg)
{
use(arg);
}

Quel est le probleme?


C'est que c'est encore plus facile de faire des erreurs et qu'en lisant
ca, je me demanderais vraiment si le programmeur etait etourdi. Pour moi
il est clair qu'un tel usage *doit* etre documente et donc avoir un
(void)self en plus ne me pose pas de probleme et renforce meme la
documentation (qui devient presque optionnelle).

En C++ c'est different. Cela peut eviter d'instancier un template en
precisant que le parametre n'est plus utilise et simplifier la tache du
compilo.

a+, ld.


Avatar
James Kanze
Laurent Deniau writes:

|> James Kanze wrote:
|> > Laurent Deniau writes:
|> > |> James Kanze wrote:
|> > |> > Laurent Deniau writes:
|> > |> > Pourquoi pas. Si je voulais vraiement faire ce genre
|> > |> > d'argument, j'aurai pris GB_Format, qui est 100% compatible
|> > |> > avec les chaînes de formattages X/Open (pré C99, c-à-d sans
|> > |> > le formattage hex des flottants). On peut le faire en C++.
|> > |> > Mais je voulais plutôt une discussion plus général, sur une
|> > |> > question du genre : qu'est-ce qui fait qu'une technique de
|> > |> > formattage est bien ou non ?
|> > |> - la simplicite,
|> > |> - la flexibilite,
|> > |> - la robustesse,
|> > |> - la rapidite.
|> > |> Maintenant que j'ai repondu a ta question, on fait quoi? ;-)
|> > Je te donne une implémentation qui remplit toutes tes exigeances :
|> > void
|> > format( void* )
|> > {
|> > }
|> > C'est simple, flexible, robuste et on ne peut plus rapide.

|> simple, non. Ce n'est pas parce que je dois appeler une seule
|> fonction avec un seul argument que cela est simple. Ton void* doit
|> pointer vers qqchose qu'il faut configurer et qui doit contenir
|> toute l'info necessaire a la flexibilite demandee.

Mon void* peut même très bien être nul, puisque je ne le déréférence
pas. Tu sembles avoir râté mon point : qu'avant de définir réelement ce
qu'on doit faire, tes critères n'ont pas de sens.

En fait, on s'adresse à un aspect différent du problème. Pour moi, il
s'agit d'abord à faire un cahier de charges -- sans cahier de charges,
tes critère n'ont aucun sens.

|> flexible, peut-etre. Ca depend de ce que tu mets derriere le void*.
|> Mais la fexibilite sera inversement proportionnelle a la simplicite.

|> robuste, idem.
|> rapide, idem.

|> > En fait, on était en train de comparer des syntaxes de formattage
|> > de sortie. Or, pour comparer, il faut savoir quel sont les
|> > critères de

|> Non, j'etais entrain de comparer quel sont les elements essentiels
|> pour pouvoir repondre aux criteres et d'y associer une interface
|> simple.

C'est ce que j'ai compris. Or que je me plaçais bien en avant : la
définition des critères.

[...]
|> > n'adresses en rien le problème de base : formatter pour quoi faire
|> > ? Si je n'ai pas besoin de l'internationalisation, par exemple, je
|> > peux bien faire plus simple pour l'utlisateur.

|> L'internationalisation n'est pas le seul probleme de formatage,

Tout à fait. Pour certains, c'est même un non-problème ; pour d'autres,
c'est un problème extrèmement complexe. Une solution qui permet la
gestion de toutes les subtilités grammatiques (les duels de certains
langages, etc.) risque d'être complexe au point de ne pas être
utilisable pour ceux qui n'ont pas besoin de tout ça.

|> meme si c'est un probleme tres complexe en soi. Mais je dirais que
|> ca fait parti de la couche 'bas niveau' du formatage, juste au
|> dessus de la couche de conversion et de bufferisation.

Je ne suis pas sûr. Je crains que c'est un problème qui pénêtre tous les
niveaux.

|> > |> Le probleme (comme d'habitude), c'est de trouver l'interface qui
|> > |> repond aux qualites ci-dessus.

|> > Avant de considérer ces qualités (qui en fait pour la plupart
|> > concerne plus l'implémentation que l'interface), je dirais qu'il
|> > faut définir ce qu'on veut accomplir avec l'interface.

|> Formater des donnees de maniere generique quelque soit le format
|> (inclus binaire, xdr, texte et texte structure) avec la possibilite
|> de l'etendre facilement, avec (presque) aucun couplage entre les
|> classes de donnees et les classes de formatage pour avoir la
|> possibilite d'introduire de nouveaux formats pour une classe 'data'
|> sans toucher a cette derniere.

En fait, tout faire. À la rigueur, je n'ai plus besoin d'autre code.

|> Si je prends l'exemple des IOStream du C++, autant je trouve que les
|> couches existantes du C (transport, buffering & low-level
|> formatting) ont bien ete classerisees (structurees en classes, je
|> sais pas ce qu'on doit dire ;-)) autant je trouve que cote
|> *formatage* il n'y a aucune inovation et l'ensemble reste tres
|> statique et complexe.

Encore, tout dépend ce qu'on a à faire. Dans l'ensemble, je suis
d'accord avec ton évalutation, mais j'ai eu des cas aussi où les
iostream était la solution parfaite.

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
Avatar
James Kanze
Emmanuel Delahaye writes:

|> James Kanze wrote on 13/11/04 :
|> > Je te donne une implémentation qui remplit toutes tes exigeances :

|> > void
|> > format( void* )
|> > {
|> > }

|> > C'est simple, flexible, robuste et on ne peut plus rapide.

|> Ne compile pas. Il manque le nom du paramètre.

Il faut le nom du paramètre ? (Pas en C++. Et je croyais que le C était
compatible à cet égard.)

--
James Kanze
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Pierre Sémard, 78210 St.-Cyr-l'École, France +33 (0)1 30 23 00 34
7 8 9 10 11