Après J'essaie d'obtenir une fonction que je peux appeler avant une invite d'entrée de l'utilisateur comme aussi loin que je peux Comprendre la fonction nécessaire est quelque chose qui afflique complètement la saisie standard. C'est ce que je veux. C'est ce que je veux. Donc, pour le but de cette fonction, le en utilisant Tous les trois travaillent aussi loin que je pouvais trouver par jugement et par les références. Mais avant d'utiliser l'un de ces codes dans tous mes codes, je voulais savoir si les bugs ont des bugs? P> EDIT: P> Merci à mark Lakata pour un bogue en 3ème. Je l'ai corrigé dans la question. P> EDIT2: P> Mark Lakata Code> a souligné que la poubelle n'est pas correctement définie dans ma question que je suis venu avec cela. Je garderai cette mise à jour pour éviter les confusions.
printf ("Entrez votre choix :); CODE> suivi d'un
scanf code> et assurez-vous que seules les choses entrées après l'invite seront numérisées par
scanf code> comme entrée valide. p>
"orbage" code> est tout dans l'entrée de l'utilisateur, c'est-à-dire l'entrée de l'utilisateur avant cette entrée Invite de l'utilisateur. p>
scanf () code> in c Il y a toujours le problème d'une entrée supplémentaire située dans le tampon d'entrée. Alors je cherchais une fonction que je Appelez après chaque appel de Scanf pour remédier à ce problème. J'ai utilisé Ceci ,
5 Réponses :
getline () est en standard C ++ non standard C. getchar () est dans Standard C. J'ai l'une des méthodes utilisant GetCharar () mais ne comprend pas comment GetChartar () peut être utilisée pour lire des flotteurs d'INT, etc.
Vous devez utiliser sscanf code> lire à un tampon local et utiliser
sscanf code>,
strtol code>,
strtof code>.
Le code utilise, plus ou moins, le posix getline () < / code>
fonction. Le "ou moins" est que la variable de taille tampon ( nbytes code>) doit être de type
taille_t code> plutôt que
int code>. En général, vous devriez également libérer le tampon. Ici, cela n'a pas beaucoup d'importance, mais s'il s'agissait d'une fonction plutôt que du programme
Main () Code>, cela importerait.
Les 2 premiers exemples utilisent une fonctionnalité de Scanf que je ne connaissais même pas existait et je suis sûr que beaucoup d'autres personnes ne savaient pas. Être capable de soutenir une caractéristique à l'avenir est important. Même s'il s'agissait d'une fonctionnalité bien connue, il sera moins efficace et plus difficile de lire la chaîne de format que votre 3ème exemple. P>
Le troisième exemple a l'air bien. P>
(Modifier l'historique: j'ai commis une erreur disant que l'ANSI-C n'a pas garanti une évaluation de gauche à droite de && et a proposé un changement. Toutefois, ANSI-C garantit une évaluation de gauche à droite de &&. Je ne suis pas sûr de K & R C, mais je ne trouve aucune référence à elle et personne ne l'utilise de toute façon ...) P>
+1 pour le bogue que vous avez souligné dans le 3ème. N'a pas vu ça. Environ 1er et 2ème, ils n'utilisent aucune variable supplémentaire pendant que le 3ème a des appels de fonction répétés. Donc, l'un de ceux-ci ne devrait-il pas être plus efficace?
Regardez les internes de Scanf et vous verrez qu'il est beaucoup moins efficace. GetCharg () (selon la mise en œuvre), d'autre part est très simple et que certaines implémentations pourraient même être inlinées dans votre code, ce qui le rend super rapide.
Qu'entendez-vous par inlined? Je ne connais pas le terme. Est page d'expansion en ligne Wikipedia se réfère à la même chose que vous parlez de?
Est Ceci se référant à la même inlinisation que vous parlez de ? Cela a eu une explication plus simple.
Inline signifie qu'il est écrit comme un appel de fonction, mais c'est plus comme une macrodefine macro. Il n'y a pas de frais générale d'appeler la fonction et l'optimiseur peut également optimiser l'utilisation du registre. C ++ a le mot-clé code> inline code> à "Forcer", mais de nombreux compilateurs C le feront automatiquement avec une forte optimisation. La règle numéro un de la programmation est cependant d'obtenir un programme que fonctionne d'abord i>, puis vous souciez d'optimisation ultérieure.
Le code d'origine était ((c = getchar ())! = '\ N' && c! = Eof) code>. Ceci fait i> garantit que l'affectation à
C code> est terminée avant que le deuxième opérande soit évalué; L'opérateur
&& code> est Évaluation du court-circuit i> et introduit un point de séquence. Cela n'a pas changé entre ANSI (C89) et C90.
Je n'ai pas ma copie de K & R1 Handy, mais mon souvenir est que && code> toujours court-circuité depuis leur introduction. Dans tous les cas, l'IMHO Mangling Code pour soutenir les compilateurs de Pre-C89 n'est pas pratique.
Je pense que si vous voyez soigneusement à droite de cette page, vous verrez de nombreuses questions similaires à la vôtre. Vous pouvez utiliser fflush () sur Windows. P>
Ce n'est pas nécessaire. Cela dépend du compilateur que j'utilise sur Windows. J'utilise le code: Blocks IDE avec le compilateur GCC. Il ne permet pas de rincer STDIN en utilisant fflush () code>. De plus, la question n'est pas spécifique à C sous Windows, il s'agit d'une norme C.
Ce que vous pouvez faire référence à i.e. fflush () code> Travailler pour Windows serait spécifique aux produits Microsoft s'il est documenté sur MSDN I.e sur Visual Studio ou d'autres produits Microsoft.
fflush code> est destiné à effacer les tampons de poignée de fichier (c'est-à-dire au niveau du pilote ou au niveau de la mise en mémoire tampon STDIO), pas pour la lecture à la fin de la ligne de texte.
Les deux premiers sont subtilement différents: ils lisent et ignorent tous les caractères jusqu'à une nouvelle ligne. Ensuite, le premier saut tous les espaces blancs consécutifs, le prochain caractère que vous lisez sera non-blanc.
La seconde lit et ignore les caractères jusqu'à ce qu'il rencontre une nouvelle ligne puis se lit (et rejette) exactement un autre caractère. . p>
La différence apparaîtra si vous avez (par exemple) texte double espacé, comme: p> supposons que vous lisez quelque part dans le Milieu de la ligne 1. Si vous exécutez ensuite le premier, le caractère suivant que vous avez lu sera le «L» en ligne 2. Si vous exécutez la seconde, le prochain caractère que vous avez lu sera la nouvelle ligne entre la ligne 1 et la ligne 2. P> Quant au troisième, si j'allais faire cela du tout, je ferais quelque chose comme: p> comme pour les différences de performance: puisque vous traitez avec des E / S pour commencer avec , il y a peu de questions raisonnables que toutes ces personnes seront toujours définies par I / O. Malgré sa complexité apparente, Aussi de toute la maintenabilité: IMO, quiconque qui prétend savoir C em> devrait em> Connaissez la conversion du jeu de numérisation pour && code> force un point de séquence, de sorte que son opérande gauche est évalué en premier. Ensuite, il y a un point de séquence. Ensuite, si et seulement si l'opérande gauche évalué à
true code>, il évalue son opérande droit. P>
scanf code> (et société) est généralement utilisé et optimisé avec soin sur des années d'utilisation. Dans ce cas, la boucle laminée à la main peut être un peu plus lente (par exemple, si le code pour
getchar code> ne peut pas être étendu en ligne) ou il peut s'agir de la même vitesse. La seule façon dont il reste une chance d'être significativement plus rapide, c'est si la personne qui a écrit votre bibliothèque standard était incompétente. P>
scanf code>. Ce n'est ni nouvelle ni science de fusée. Toute personne qui ne sait pas que ce n'est vraiment pas un programmeur C compétent. P> p>
Votre explication a aidé. Je ne pouvais pas comprendre l'un d'eux avant cela. J'ai essayé les deux. Mais pour une raison quelconque, votre explication n'a pas été tenue et les deux travaillaient dans le cas de test 1 ajouté à la question. Est-ce que c'est due à Scanf code> S interne? Des conseils concernant le 3ème cas de test?
@Aseembansal: Vos tests sont un peu brisés car % d code> sauteront d'un espace blanc, ainsi de suite, cela ne fait aucune différence si la principale espace était déjà ignorée. Essayez d'utiliser
% c code> après.
@Jerrycoffin Vous voudrez peut-être reconsidérer votre dernier paragraphe; Vos deux premiers paragraphes donnent sur le fait que si la poubelle consistait simplement à une nouvelle ligne, alors scanf ("% * [^ \ n]% * c"); code> et
scanf ("% * [ ^ \ n] \ n "); code> arrêter après le premier spécificateur car il n'a pas fait correspondre à rien. Donc ni ne résout le problème. (Une solution serait de casser chacun en deux appels Scanf).
@MattMCnabB: Cela me semble que vous demandez simplement quelque chose que la question ne posait pas (au moins à l'époque - il est sous-jacent édition substantielle depuis). En fin de compte, c'est une question de ce qu'il veut vraiment. Il est certainement vrai que Scanf cessera de numériser dès que toute conversion échoue. S'il souhaite que cela se produise ou veuille la rompre en deux appels pour lire un personnage même s'il n'ya rien précédemment ne semble être ouvert à la question.
De nombreuses autres solutions ont le problème qu'elles provoquent le programme de pendre et d'attendre l'entrée lorsqu'il n'y a plus rien à affleurer. En attente de sur Linux, les suivants feront un non-bloquant em> affleurant: p> la page de l'homme Linux dit que Le drapeau EOF code> est faux parce que vous n'obtenez pas cela tant que l'utilisateur ferme complètement l'entrée!
fflush code> sur
stdin code> est non standard, mais "la plupart des autres implémentations se comportent la Identique que Linux. " p>
msg_dontwait code> est également non standard (il provoque" code> recv code> pour revenir immédiatement s'il n'y a pas de données à livrer) . p> p>
Les réponses doivent utiliser uniquement les fonctions standard C i>
Pourquoi est-il marqué avec optimisation?
@ 0x90 Parce que je voulais savoir s'il est optimal et s'il n'est pas possible d'optimiser.
ok alors lisez ce Stackoverflow.com/questions/5638999/...
@ 0x90 La réponse acceptée est bonne lorsque je lisons de grandes entrées à partir de fichiers, mais lorsque je lisons de très petites entrées telles que 1 ou 2 entiers, l'approche de la question liée ne serait pas moins optimale en raison des appels à Malloc, puis de l'analyse des cordes dans les entiers?
Vous pouvez utiliser évitez MALLOC avec déclarer
Char BUF [256]; code>
fgets () ou sscanf () ????
Critique constructive: si vous voulez dire que vous voulez dire au moins laissez un commentaire pour l'expliquer
Adem, je pense que vous allez mal ce problème de manière incorrecte. Qu'est-ce que "ordures" entrée? Qu'essayez-vous de lire? Essayez-vous simplement de sauter tout ce qui n'est pas numérique?
@Marklakata J'essaie d'obtenir une fonction que je peux appeler avant une invite d'entrée de l'utilisateur, comme
printf ("Entrez votre choix :); code> suivi un
scanf code> et assurez-vous que Seuls les choses entrées après l'invite seraient numérisées par
scanf code> comme entrée valide. Autant que je puisse comprendre la fonction nécessaire, c'est quelque chose qui flitons complètement d'entrée standard. C'est ce que je veux. Aux fins de cette fonction, le
"orbage" code> est tout dans l'entrée de l'utilisateur, c'est-à-dire l'entrée de l'utilisateur entier avant l'invite de l'utilisateur.
@Marklakata ai tort dans l'analyse du problème ou cela a-t-il ajouté de la clarté à la situation?
Vous ne pouvez pas utiliser Standard C pour faire ce que vous voulez faire. Standard C n'est pas destiné à une entrée d'utilisateur interactive, où l'utilisateur peut taper des informations indésirables avant ou après l'invite le programme. Il y a des moyens autour de cela, mais je ne pense pas que cela vaut la peine d'être effort. La plupart des gens n'utilisent pas de participation de console interactive pour les applications de toute façon, et s'ils le font, ils sont censés ne pas taper des ordures.
Si vous souhaitez "rincer le flux d'entrée", vous devez écrire du code qui accède directement à la console, pas seulement STDIN (qui est toujours tamponné). Il existe des packages tels que
malédictions code> qui font cela ... mais comme je l'ai dit, ce n'est probablement pas ce que vous voulez faire.