jetez un coup d’œil au tampon d’entrée et effacez les caractères supplémentaires en C

StackOverflow https://stackoverflow.com/questions/844847

  •  20-08-2019
  •  | 
  •  

Question

Si je souhaite recevoir une entrée d'un caractère en C, comment puis-je vérifier si des caractères supplémentaires ont été envoyés et, dans l'affirmative, comment puis-je l'effacer?

Existe-t-il une fonction qui agit comme getc (stdin), mais qui ne demande pas à l'utilisateur de saisir un caractère, je peux donc simplement mettre while(getc(stdin)!=EOF);? Ou une fonction permettant de jeter un coup d’œil sur le caractère suivant dans la mémoire tampon, et si elle ne renvoie pas la valeur NULL (ou quoi que ce soit là), je pourrais appeler une fonction (nother) qui supprime stdin?

Modifier

Donc, pour le moment, scanf semble faire l'affaire, mais existe-t-il un moyen de le lire pour lire la chaîne entière , jusqu'à la nouvelle ligne? Plutôt que vers les espaces les plus proches? Je sais que je peux simplement mettre & Quot;% s% s% s ! ou quoi que ce soit dans la chaîne de format mais puis-je gérer un nombre arbitraire d'espaces?

Était-ce utile?

La solution

Vous ne pouvez pas vider le flux d'entrée. Si vous le faites, vous invoquerez un comportement indéfini. Votre meilleur pari est de faire:

int main() {
  int c = getchar();
  while (getchar() != EOF);
  return 0;
}

Pour utiliser scanf la magie:

#include <stdio.h>
#include <stdlib.h> 

#define str(s) #s
#define xstr(s) str(s)
#define BUFSZ 256

int main() {
  char buf[ BUFSZ + 1 ];
  int rc = scanf("%" xstr(BUFSZ) "[^\n]%*[^\n]", buf);
  if (!feof(stdin)) {
    getchar();
  }
  while (rc == 1) {
    printf("Your string is: %s\n", array);
    fflush(stdout);
    rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);
    if (!feof(stdin)) {
        getchar();
    }
   }
   return 0;
}

Autres conseils

Vous pouvez utiliser getline pour lire une ligne entière d'entrée.

Alternativement (en réponse à votre question initiale), vous pouvez appeler select ou poll sur stdin pour voir s'il y a des caractères supplémentaires à lire.

J'ai eu un problème similaire aujourd'hui et j'ai trouvé un moyen qui semble fonctionner. Je ne connais pas les détails de votre situation, donc je ne sais pas si cela fonctionnera pour vous ou non.

J'écris une routine qui doit extraire un seul caractère du clavier et ce doit être l'une des trois frappes au clavier spécifiques (un "1", un "2" ou un "3"). Si ce n’est pas le cas, le programme doit envoyer un message d’erreur et une boucle pour un nouvel essai.

Le problème est qu’en plus du caractère que j’ai entré qui est renvoyé par getchar (), la frappe sur la touche "Entrée" (qui envoie la frappe au programme) est enregistrée dans un tampon d’entrée. Ce caractère de nouvelle ligne (non imprimable) est ensuite renvoyé par la fonction getchar () dans la boucle de correction d'erreur, ce qui entraîne un second message d'erreur (puisque le caractère de nouvelle ligne n'est ni un "1", ni un "2" , ni un '3'.)

Le problème est encore plus compliqué car je prends parfois de l'avance sur moi-même et au lieu de saisir un seul caractère, je vais entrer le nom du fichier demandé par l'une de ces options. Ensuite, j'ai toute une chaîne de caractères indésirables dans le tampon, ce qui entraîne une longue liste de messages d'erreur qui défilent vers le bas de l'écran.

Pas cool.

Ce qui semble l'avoir corrigé, cependant, est le suivant:

c = getchar();  // get first char in line
while(getchar() != '\n') ; // discard rest of buffer

La première ligne est celle qui utilise réellement le caractère que je saisis. La deuxième ligne élimine tout résidu restant dans le tampon d’entrée. Il crée simplement une boucle qui extrait un caractère à la fois de la mémoire tampon d’entrée. Aucune action spécifiée ne doit avoir lieu pendant que l'instruction est en boucle. Il lit simplement un caractère et, s'il ne s'agit pas d'une nouvelle ligne, revient au suivant. Quand il trouve une nouvelle ligne, la boucle se termine et passe au prochain ordre de travail du programme.

Nous pouvons créer une fonction pour vider le tampon du clavier, comme ceci:

#include <stdio.h>

void clear_buffer(){
   char b;
   //this loop take character by character in the keyboard buffer using 
   //getchar() function, it stop when the variable "b" was
   //enter key or EOF.
   while (((b = getchar()) != '\n') && (b != EOF));
}

int main()
{
    char input;
    //get the input. supposed to be one char!
    scanf("%c", &input); 
    //call the clearing function that clear the buffer of the keyboard 
    clear_buffer(); 
    printf("%c\n",input); //print out the first character input
    // to make sure that our function work fine, we have to get the
    // input into the "input" char variable one more time
    scanf("%c", &input); 
    clear_buffer();  
    printf("%c\n",input);
    return 0;
}

Utilisez une lecture qui prendra beaucoup de caractères (plus de 1, peut-être 256) et voyez combien de caractères sont réellement renvoyés. Si vous en avez plus d'un, vous savez; si vous n'en avez qu'un, c'est tout ce qui était disponible.

Vous ne parlez pas de plateforme, et cela devient assez compliqué assez rapidement. Par exemple, sous Unix (Linux), le mécanisme normal renverra une ligne de données - probablement le caractère que vous étiez après et une nouvelle ligne. Ou peut-être persuadez-vous votre utilisateur de taper ^ D (valeur par défaut) pour envoyer le caractère précédent. Vous pouvez également utiliser des fonctions de contrôle pour mettre le terminal en mode brut (comme des programmes tels que vi et emacs do).

Sous Windows, je n'en suis pas si sûr. Je pense qu'il existe une getch() fonction qui répond à vos besoins.

Pourquoi n'utilisez-vous pas scanf au lieu de getc? En utilisant scanf, vous pouvez obtenir la chaîne complète.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top