How can I clear what scanf read?

2019-08-11 17:36发布

问题:

I want to be able to clear the value of what scanf read in. In other words, I want to delete the value that was read in by scanf.

Here is my sample code:

#include <stdio.h>
#include <signal.h> 
#include <sys/time.h>

volatile sig_atomic_t gotsignal;


void handler(){

gotsignal = 1;

}

int main(){

struct sigaction sig;

sig.sa_handler = handler; 
sig.sa_flags = 0; 
sigemptyset(&sig.sa_mask); 

alarm(5);
sigaction(SIGALRM, &sig, NULL);


int value;

while(!gotsignal){
    printf("Insert a value: \n");
    scanf("%d", &value);
}
}

Output:

Insert a value: 
5(dont press enter)[JPS@localhost c]$ 5 <-

Is it possible(if yes how) to clear the 5?

I have been reading about terminal settings, fflushs, stdin, but i couldn't figure it out. Any help please?

EDIT: After a lot of trys i think i found something that works. If anyone has this problem this worked for me(not sure if it works on other systems and stuff, kinda new to this):

#include <stdio.h>
#include <signal.h> 
#include <sys/time.h>
#include <termios.h>
#include <unistd.h>


volatile sig_atomic_t gotsignal;


void handler()
{

gotsignal = 1;

}


int main(){

struct sigaction sig;

sig.sa_handler = handler; 
sig.sa_flags = 0; 
sigemptyset(&sig.sa_mask); 

alarm(5);
sigaction(SIGALRM, &sig, NULL);


int value;
while(!gotsignal){
    printf("Insert a value: \n");
    scanf("%d", &value);
}
printf("\n");
tcflush(STDOUT_FILENO,TCIOFLUSH); <-important bit!

return 0;

}

Output:

Insert a value: 
5
Insert a value: 
5(no enter was pressed)!
[JPS@localhost c]$ <- NO MORE NR 5! :D

回答1:

You might use the readline library. But I'm not sure to understand what you mean by "clear the 5".

The simplest example might be

// file testrl.c
#include <readline/readline.h>
#include <stdlib.h>

int main () 
{
   char bufprompt[20];
   char* lin = NULL;
   int cnt = 0;
   for (;;) {
     memset(bufprompt, 0, sizeof(bufprompt));
     cnt++;
     snprintf(bufprompt, sizeof(bufprompt)-1, "%d: ", cnt);
     lin = readline(bufprompt);
     if (!lin) 
       break;
     printf("you typed %s\n", lin);
     free (lin);
   }
   return 0;
}

Compile the above with gcc -Wall -g testrl.c -o testrl -lreadline

See also this question



回答2:

See these links for good answers:

  • How can I flush pending input so that a user's typeahead isn't read at the next prompt? Will fflush(stdin) work?
  • If fflush won't work, what can I use to flush input?

To quote the most interesting:

There is no standard way to discard unread characters from a stdio input stream. Some vendors do implement fflush so that fflush(stdin) discards unread characters, although portable programs cannot depend on this. (Some versions of the stdio library implement fpurge or fabort calls which do the same thing, but these aren't standard, either.) Note, too, that flushing stdio input buffers is not necessarily sufficient: unread characters can also accumulate in other, OS-level input buffers. If you're trying to actively discard input (perhaps in anticipation of issuing an unexpected prompt to confirm a destructive action, for which an accidentally-typed ``y'' could be disastrous), you'll have to use a system-specific technique to detect the presence of typed-ahead input; see questions 19.1 and 19.2. Keep in mind that users can become frustrated if you discard input that happened to be typed too quickly.