OVH Cloud OVH Cloud

Vider le buffer associe a stdin

98 réponses
Avatar
korchkidu
Bonjour,

je me pose une question par rapport a la maniere classique de vider le
buffer associe a stdin:

c = getchar();
if (c != ’\n’)
while ( (getchar()) != ’\n’) {
};

Que se passe t-il si stdin ne contient aucun \n? (fichier contenant une
ligne mais aucun \n par exemple). Dans ce cas, il me semble que l'on
pourrait avoir un probleme non?

Comment feriez vous pour resoudre ce probleme? (J'ai bien une petite
idee mais je prefere savoir si c'est la bonne..;) )

Merci d'avance pour vos reponses,
K.

10 réponses

Avatar
Laurent Deniau
Anthony Fleury wrote:
Laurent Deniau wrote:


Jean-Marc Bourguet wrote:



Quand un typedef avait le meme identifieur que le tag d'une struct,
c'etait un typedef sur la struct. Donc pas de probleme.


Si ca compile pas en C++ et c'est legal (voir courant) en C.



Ca m'a pourtant l'air de compiler en C++. En fait je suis dans ma tête


Mea culpa. J'ai dit une betise en allant trop vite (on m'attendait pour
la pause ;-)

De plus OOC est bourre de typedef struct T T; et il est compatible C++.
Je serais donc le premier em*de par ca ;-)

A quels problemes *silencieux* fais-tu allusion?


Pour la plupart ils ne sont pas silencieux mais demande du travail.
cf mon autre post pour les problemes




Je ne sais pas si c'est parce que je me suis mis au C++ un peu plus
sérieusement et donc ne suis plus vraiment objectif sur ce sujet, mais je
trouve que tous les exemples de codes qui ne fonctionnent pas en C++ et
fonctionnent en C sont du « mauvais C ». (mis à part le cast des void*
forcé par le C++)


c'est un point de vue.

a+, ld.



Avatar
K. Ahausse
"Anthony Fleury" a écrit dans le message de
news:418a442f$0$4415$
Charlie Gordon wrote:

"Laurent Deniau" wrote in message
news:cmd5a5$hgm$

- pas de goto.
s'il y a que le compilateur C++ rejette, c'est sans doute qu'il faut

fixer


le code C aussi.


Oui et de toute facon les goto en C[++] c'est mal © ® (TM)


le PB en C++ le voilà :

int toto (void)
{
int A=0 ;
goto Fin ;

int B = 0 ;

Fin:
return A ;
}


Et le compilateur indique que le 'goto' empeche l'initialisation de B, ce
qui est effectivement néfaste.
Il suffit d'écrire :
{ int B=0; }
pour que tout redevienne OK.

PS : Pour corriger un préjugé sans fondement : l'utilisation de goto dans du
C/C++ est parfaitement justifiable.



Avatar
Jean-Marc Bourguet
Laurent Deniau writes:

int x[99];
void f()
{
struct x { int a; };
sizeof(x); /* size of the array in C, size of the struct in C++ */
}


Ah oui. Apparemment ce n'est pas tombe. Faut dire qu'il doit pas y
avoir beaucoup de definition de struct locales a des fonctions et
que la plupart des utilisations doivent entrainer un diagnostic. (Si
on utilise sizeof(x), il y a des chances qu'on utilise le x originel
aussi et ca va clasher. Ok, il doit y avoir moyen de batir quelque
chose de plus ou moins vraissemblable mais c'est rare).

ou un typedef (le probleme peut etre silencieux et tres vicieux).
Quand un typedef avait le meme identifieur que le tag d'une struct,

c'etait un typedef sur la struct. Donc pas de probleme.


Si ca compile pas en C++ et c'est legal (voir courant) en C.


J'ai toujours parle volontairement de problemes silencieux. C'est pas
pour rien.

Ils ont ete testes dans le details ces millions de lignes de code?
Pas mal. Nos tests (ceux de la R&D) ne couvrent certainement pas

assez, mais quand meme pas mal. Plus les tests de la validation, plus
les tests de beta (mais on n'y est pas encore, le changement a ete
fait il y a 4 ou 5 mois et le produit ne sera pas chez les clients
avant 6 mois -- c'est naturellement quelque chose qui a ete fait au
debut d'un cycle).


Donc c'est un processus long et lourd.


La transition c'est faite me semble-t'il sur une quinzaine de jours.
Je n'ai aucune idee du nombre de personnes impliquees ni de la
proportion de leur temps passe a cela. On fait aussi autre chose
depuis.

Ce n'est pas une recompilation a la legere...


Quand tu lances une recompilation de ce genre avec du C encore K&R par
endroit, tu t'y attends.

Si tu commences, ca ne me semble pas deraisonnable si on veut faire du
C de se restreintre au sous-ensemble commun du C et du C++ et de
controler avec les deux compilateurs s'ils sont disponibles. La
question est alors pourquoi ne pas faire carement du C++?

presentation des arguments par quelqu'un qui n'est pas convaincu et
qui n'a eu connaissance de ces arguments que par des gens non
convaincus n'est vraissemblablement pas significative. Une des
raisons donc est qu'on a remplace un composant d'assez bas niveau par
quelque chose ecrit en C++ et qu'il y a un desir de se passer de la


Il aurait ete peut-etre moins couteux de faire une interface au code C++
specialisee pour le C.


Comme je le disais, elle est la pour 90% au moins des fonctionnalites.

Une question au hasard. Vous gerez comment les exceptions dans votre
code C avec tous ses pointeurs et ses mallocs (ou wrapper
equivalent) si vous avez du C++ comme couche bas niveau du C?


Simple: si des exceptions s'echappent de la couche d'interface, il y a
un probleme dans celles-ci. Si le code qui se met a utiliser le
composant directement n'est pas modifie pour intercepter les
exceptions possibles, il y a un probleme dans la modif.

couche presentant l'interface C du composant precedant (pour des
raisons de perf et d'acces a des possibilites supplementaires).
Il y


perf?


L'interface C est celle du composant precedant. Il y a des operations
qui sont emulees de facon couteuses (et d'autres qui sont moins
cheres). Acceder a la nouvelle interface directement peut etre un
gain.

restructuration et simplication surement.


Aussi, je le disais.

a aussi un desir de restructurer des choses en utilisant les
possibilites d'abstraction supplementaires du C++.


il n'y aurait pas un facteur marketing derriere tout ca?


Non. Le facteur marketing explique des decisions que je n'approuve
pas toujours mais a ma connaissance pas ici.

A+
--
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
Anthony Fleury
K. Ahausse wrote:


"Anthony Fleury" a écrit dans le message de
news:418a442f$0$4415$
Oui et de toute facon les goto en C[++] c'est mal © ® (TM)
le PB en C++ le voilà :

int toto (void)
{
int A=0 ;
goto Fin ;
int B = 0 ;
Fin:
return A ;
}
Et le compilateur indique que le 'goto' empeche l'initialisation de B, ce
qui est effectivement néfaste.


Ah merci je ne savais pas que ca posait problème dans ce cas.

Il suffit d'écrire :
{ int B=0; }
pour que tout redevienne OK.


Alors en fait, je ne suis pas sûr de comprendre. Si je ne m'abuse,
d'ailleurs, et si j'ai bien compris, c'est valable aussi en C99 qui
autorise des définitions de variable en milieu de code.

Ce que j'en comprendrais, c'est qu'à la fin de la fonction toto on tente de
« libérer » (appel du destructeur en C++) la variable B, correct ? C'est la
seule chose que je vois dans ce code qui pourrait causer problème, et qui
pourrait être résolu par le { int B = 0; }. Cependant, si c'est bien le
cas, d'une part ca rend goto inutilisable en C99 et en C++, à moins de
mettre toutes les variables dans des blocs { }... Et deuxièmement, si c'est
vraiment le cas, c'est pour moi pas un problème de C++ ou de C99 mais de
compilateur non ? car le programme n'est pas passé par le int B = 0; il n'a
donc rien à dire.

PS : Pour corriger un préjugé sans fondement : l'utilisation de goto dans
du C/C++ est parfaitement justifiable.


Oui oui, il manquait un « :-) » derrière les © ® ... Cependant, je pense que
l'usage qu'il peut en être fait est plus que limité, et que goto n'est
acceptable que dans un nombre très restreint de cas.

Anthony
--
Alan Turing thought about criteria to settle the question of whether
machines can think, a question of which we now know that it is about as
relevant as the question of whether submarines can swim.
-- Dijkstra


Avatar
Laurent Deniau
Jean-Marc Bourguet wrote:
Laurent Deniau writes:
Une question au hasard. Vous gerez comment les exceptions dans votre
code C avec tous ses pointeurs et ses mallocs (ou wrapper
equivalent) si vous avez du C++ comme couche bas niveau du C?



Simple: si des exceptions s'echappent de la couche d'interface, il y a
un probleme dans celles-ci. Si le code qui se met a utiliser le
composant directement n'est pas modifie pour intercepter les
exceptions possibles, il y a un probleme dans la modif.


Tu veux dire que toutes les methodes C++ de votre couche bas niveau sont
qualifiees avec throw(). A ma connaissance ce n'est pas bon pour les
perfs sauf compilo tres efficace sur un try.

a+, ld.


Avatar
K. Ahausse
"Anthony Fleury" a écrit dans le message de
news:418a5aaf$0$594$
K. Ahausse wrote:


"Anthony Fleury" a écrit dans le message
de


news:418a442f$0$4415$
Oui et de toute facon les goto en C[++] c'est mal © ® (TM)
le PB en C++ le voilà :

int toto (void)
{
int A=0 ;
goto Fin ;
int B = 0 ;
Fin:
return A ;
}
Et le compilateur indique que le 'goto' empeche l'initialisation de B,
ce


qui est effectivement néfaste.


Ah merci je ne savais pas que ca posait problème dans ce cas.

Il suffit d'écrire :
{ int B=0; }
pour que tout redevienne OK.


Alors en fait, je ne suis pas sûr de comprendre. Si je ne m'abuse,
d'ailleurs, et si j'ai bien compris, c'est valable aussi en C99 qui
autorise des définitions de variable en milieu de code.

Ce que j'en comprendrais, c'est qu'à la fin de la fonction toto on tente
de

« libérer » (appel du destructeur en C++) la variable B, correct ? C'est
la

seule chose que je vois dans ce code qui pourrait causer problème, et qui
pourrait être résolu par le { int B = 0; }. Cependant, si c'est bien le
cas, d'une part ca rend goto inutilisable en C99 et en C++, à moins de
mettre toutes les variables dans des blocs { }... Et deuxièmement, si
c'est

vraiment le cas, c'est pour moi pas un problème de C++ ou de C99 mais de
compilateur non ? car le programme n'est pas passé par le int B = 0; il
n'a

donc rien à dire.


Mon exemple n'est pas parfait. Le problème tel que je l'ai compris est dans
le cas ou la variable B est initialisée dans la branche masquée par le goto,
et, cette variable est utilisé après le label 'fin:'. Si je reprend
l'exemple :

int toto (void)
{
int A = 0 ;
goto Fin ;

int B=0 ;

Fin:
return B ;
}

Un autre voie pour la correction est de ramener la défintion de B en début
de fonction comme cela etait le cas avant C99.

Le seul cas ou vraiment les accolades sont impératives c'est lorsque la
variable B est definie en tant que référence.

PS : Pour corriger un préjugé sans fondement : l'utilisation de goto
dans


du C/C++ est parfaitement justifiable.


Oui oui, il manquait un « :-) » derrière les © ® ... Cependant, je pense
que

l'usage qu'il peut en être fait est plus que limité, et que goto n'est
acceptable que dans un nombre très restreint de cas.


Entierement d'accord. Je l'utilise dans le seul cas de gestion d'erreur.



Avatar
Gabriel Dos Reis
Jean-Marc Bourguet writes:

| Laurent Deniau writes:
|
| > int x[99];
| > void f()
| > {
| > struct x { int a; };
| > sizeof(x); /* size of the array in C, size of the struct in C++ */
| > }
|
| Ah oui. Apparemment ce n'est pas tombe. Faut dire qu'il doit pas y
| avoir beaucoup de definition de struct locales a des fonctions et
| que la plupart des utilisations doivent entrainer un diagnostic. (Si
| on utilise sizeof(x), il y a des chances qu'on utilise le x originel
| aussi et ca va clasher. Ok, il doit y avoir moyen de batir quelque
| chose de plus ou moins vraissemblable mais c'est rare).

Je crois que le fond de la question est pourquoi il y a cette
différence. Par exemple, les deux codes suivants ont la même
siginification en C et en C++.

struct x { int a; };
void f()
{
int x[99];
sizeof(x); // size of the array "x" in C and C++
}


void g()
{
int x[99];
struct x { int a; };
sizeof(x); // size of the array "x" in C and C++
}

.
.
.

La réponse a avoir en grand partie avec la notion de portée.

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

Jean-Marc Bourguet wrote:
Laurent Deniau writes:
Une question au hasard. Vous gerez comment les exceptions dans votre
code C avec tous ses pointeurs et ses mallocs (ou wrapper
equivalent) si vous avez du C++ comme couche bas niveau du C?
Simple: si des exceptions s'echappent de la couche d'interface, il y a

un probleme dans celles-ci. Si le code qui se met a utiliser le
composant directement n'est pas modifie pour intercepter les
exceptions possibles, il y a un probleme dans la modif.


Tu veux dire que toutes les methodes C++ de votre couche bas niveau sont
qualifiees avec throw().


Non. Les fonctions qui presentent une interface C a la couche C++ le
sont logiquement mais pas en pratique (pour simplifier, elles sont
declarees dans un fichier qui est inclu par du C pur et dur). Si
elles laissent s'echapper des exceptions, il y a bien un probleme.
Mais autre que simplement la liberation des pointeurs, la logique de
l'application ne fonctionnera pas bien.

A+

--
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
Antoine Leca
En 418a5531$0$23274$, K. Ahausse va escriure:
- pas de goto.




le PB en C++ le voilà :

int toto (void)
{
int A=0 ;
goto Fin ;

int B = 0 ;

Fin:
return A ;
}


C'est un problème ? Pour qui ?

Si un compilo C a mangé cela sans broncher, c'est qu'il est franchement
récent, donc le source l'est encore plus, ce qui n'est pas le cas évoqué par
Jean-Marc.


Antoine




Avatar
Gabriel Dos Reis
Laurent Deniau writes:

| Jean-Marc Bourguet wrote:
| > Laurent Deniau writes:
| >>Une question au hasard. Vous gerez comment les exceptions dans votre
| >>code C avec tous ses pointeurs et ses mallocs (ou wrapper
| >>equivalent) si vous avez du C++ comme couche bas niveau du C?
| > Simple: si des exceptions s'echappent de la couche d'interface, il y
| > a
| > un probleme dans celles-ci. Si le code qui se met a utiliser le
| > composant directement n'est pas modifie pour intercepter les
| > exceptions possibles, il y a un probleme dans la modif.
|
| Tu veux dire que toutes les methodes C++ de votre couche bas niveau
| sont qualifiees avec throw(). A ma connaissance ce n'est pas bon pour
| les perfs sauf compilo tres efficace sur un try.

Pardon ?

(Glibc est bourré de throw() et le compilateur optimise à base de ça).

-- Gaby