10
votes

Utiliser getchar () sur c obtient "Entrée" après l'entrée

J'essaie d'écrire un programme simple qui demande à un utilisateur de choisir parmi un menu dans une boucle. J'utilise getchar () pour obtenir l'entrée, mais j'ai remarqué que lorsque je saisi un char et appuyez sur "Entrée", le programme fait deux boucles (comme si j'étais enfoncé deux fois) l'un de la charme comme une entrée et une autre pour "Entrer" comme une entrée.

Comment puis-je résoudre ce problème?


0 commentaires

5 Réponses :


1
votes

Comment sur xxx

source


1 commentaires

Je ne dois pas utiliser de chaîne ou de charcuterie (c'est un travail pour un cours)



2
votes

Ajouter un getchar () après le getchar () : p


2 commentaires

Je suppose que cela fonctionnerait, mais son anesthésique silencieux.


Cela produira des problèmes dans certains cas où l'utilisateur se retrouvera à appuyer deux fois sur Retour.



3
votes

Le moyen le plus simple consiste à filtrer la clé Entrée comme valeur de retour de getchar xxx


6 commentaires

Je suppose que vous vouliez dire getchar ()? Si oui, getchar () retourne int.


@Nyan, getchar retourne effectivement int mais il est légal d'attribuer à char via des conversions. Référence Cplusplus.com/reference/clibrary/cstdio/getchar


@Jared: Oui, mais le char est limité à (typiquement) 256 valeurs, et vous avez besoin (typiquement) 257 valeurs pour identifier Tous les caractères et EOF. C'est pourquoi getchar () retourne un int


@pmg, je suis au courant de cela. Je montre simplement ce que l'OP a demandé (comment vérifier la nouvelle ligne).


OK, mais vous pouvez démontrer avec int C aussi :-)


Je l'ai dit comme INT que Linux Man déclare de la valeur de retour de Getchar ().



4
votes

getchar () renvoie le premier caractère dans la mémoire tampon d'entrée et le supprime à partir du tampon d'entrée. Mais d'autres personnages sont toujours dans le tampon d'entrée ( \ n dans votre exemple). Vous devez effacer le tampon d'entrée avant d'appeler getchar () à nouveau: xxx


0 commentaires

1
votes

Vous avez un peu répondu à votre propre question; Vous devez faire face au personnage de la nouvelle ligne en quelque sorte.

Il y a plusieurs options. Si vos options de menu sont numérotées em>, vous pouvez utiliser scanf () code> pour lire une valeur et commutateur entier basé sur celui-ci: p> xxx pré >

L'avantage de cette option est que le spécificateur de conversion % d code> sur tout blancheur de tête, y compris des caractèresWLINE, de sorte que vous n'avez pas à vous soucier de tout \ n SCÈRE Le flux d'entrée (en fait, la plupart des spécificateurs de conversion ignorent les principaux espaces blancs; % c code> ne le permet pas de se comporter beaucoup comme getchar () code> ). p>

L'inconvénient de cette option est que si une personne grasse est un caractère non chiffré dans leur entrée, il ne sera pas lu avec le spécificateur de conversion % d code> et sera Restez coincé dans le flux d'entrée jusqu'à un appel sur getchar () code> ou scanf () code> avec un % s code> ou % c Code> Spécificateur de conversion. p>

Une meilleure option consiste à lire toutes les entrées en tant que caractères strings em> à l'aide de fgets () code>, puis d'analyse et de validation si nécessaire. P>

/**
 * Prints a prompt to stdout and reads an input response, writing
 * the input value to option.  
 *
 * @param prompt [in]  - prompt written to stdout
 * @param option [out] - option entered by user
 *
 * @return - 1 on success, 0 on failure.  If return value is 0, then option
 * is not changed.
 */
int getOption(const char *prompt, char *option)
{
  char input[3]; // option char + newline + 0 terminator
  int result = 0;

  printf("%s: ", prompt);  
  fflush(stdout);

  if (fgets(input, sizeof input, stdin))
  {
    /**
     * Search for a newline character in the input buffer; if it's not
     * present, then the user entered more characters than the input buffer 
     * can store.  Reject the input, and continue to read from stdin until
     * we see a newline character; that way we don't leave junk in the
     * input stream to mess up a future read.
     */
    char *newline = strchr(input, '\n');
    if (!newline)
    {
      printf("Input string is too long and will be rejected\n");
      /**
       * Continue reading from stdin until we find the newline
       * character
       */
      while (!newline && fgets(input, sizeof input, stdin))
        newline = strchr(input, '\n');
    }
    else
    {
      *option = input[0];
      result = 1;
    }
  }
  else
    printf("Received error or EOF on read\n");

  return result;
}


0 commentaires