1

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
octopusgrabbus
  • 10,555
  • 15
  • 68
  • 131
JPS
  • 63
  • 1
  • 8
  • Good question. I am deleting my answer, as useless. Trying `system("stty raw");` also doesn't work. Perhaps shell-dependent? – Joseph Quinsey Nov 27 '11 at 15:04

2 Answers2

3

See these links for good answers:

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.

unbeli
  • 29,501
  • 5
  • 55
  • 57
  • So, there is no way around this? With system specific you mean i could try to look for a solution for fedora, but then in ubuntu wouldn't work? – JPS Nov 27 '11 at 15:12
  • No with system specific they mean that, for example, it might work on Linux, but not on Windows or OS X. Try fpurge, should work for any linux. – unbeli Nov 27 '11 at 15:34
  • No, most recent Linux distributions would work likewise. But probably, it won't work the same on MacOSX or FreeBSD – Basile Starynkevitch Nov 27 '11 at 15:36
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

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • What i mean by clear the 5 is after the program is finished running, since he got the signal, i don't want to read the 5 and i don't want the 5 in the terminal, as he stays there, even after the program is finished. – JPS Nov 27 '11 at 15:12
  • The point is that TTY & pseudo-terminals are complex beasts on Linux, and (to summarize & simplify) part of the line buffering is done by the kernel. You really should use a library like `readline` or `ncurses` as I told you in other answers. `scanf` is not enough for you if you want to "clear the 5". – Basile Starynkevitch Nov 27 '11 at 15:15
  • I read about the readline but i didn't understand. What do i need to import? Could you give me a simple example? – JPS Nov 27 '11 at 15:24
  • I gave an example, but I did not bother testing it. It might not work! – Basile Starynkevitch Nov 27 '11 at 15:29
  • I get this: fatal error: readline.h: No such file or directory compilation terminated. Do i need to install it on my machine or? – JPS Nov 27 '11 at 15:32
  • You need to install the readline development package, ie `libreadline-dev` on Debian or Ubuntu – Basile Starynkevitch Nov 27 '11 at 15:35
  • Btw, is there any (easy) way to tell the terminal to just delete a character, like a user doing a backspace? Maybe that would fix it? – JPS Nov 27 '11 at 15:42