Как я могу понять, что читает scanf? - PullRequest
1 голос
/ 27 ноября 2011

Я хочу иметь возможность очистить значение того, что считал scanf. Другими словами, я хочу удалить значение, прочитанное scanf.

Вот мой пример кода:

#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);
}
}

Выход:

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

Можно ли (если да, как) очистить 5?

Я читал о настройках терминала, fflushs, stdin, но я не мог понять это. Любая помощь, пожалуйста?

РЕДАКТИРОВАТЬ: После многих попыток я думаю, что я нашел что-то, что работает. Если у кого-то есть эта проблема, это работает для меня (не уверен, работает ли она на других системах и прочее, вроде как новичок в этом):

#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;

}

Выход:

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

Ответы [ 2 ]

3 голосов
/ 27 ноября 2011

См. Эти ссылки для получения хороших ответов:

Чтобы процитировать наиболееинтересно:

Нет стандартного способа для удаления непрочитанных символов из входного потока stdio.Некоторые производители реализуют fflush так, что fflush (stdin) отбрасывает непрочитанные символы, хотя переносимые программы не могут зависеть от этого.(Некоторые версии библиотеки stdio реализуют вызовы fpurge или fabort , которые делают то же самое, но они также не являются стандартными.) Также обратите внимание, что очистка входных буферов stdioне обязательно достаточно: непрочитанные символы также могут накапливаться в других входных буферах уровня ОС.Если вы пытаетесь активно отбросить ввод (возможно, в ожидании неожиданного приглашения подтвердить деструктивное действие, для которого случайно введенный «y» может быть катастрофическим), вам придется использоватьспецифичная для системы методика для обнаружения наличия опережающего ввода;см. вопросы 19,1 и 19,2 .Имейте в виду, что пользователи могут расстроиться, если вы откажетесь от ввода, которое было введено слишком быстро.

1 голос
/ 27 ноября 2011

Вы можете использовать библиотеку readline .Но я не уверен, что понимаю, что вы подразумеваете под «очистить 5».

Простейшим примером может быть

// 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;
}

Скомпилируйте вышеприведенное с помощью gcc -Wall -g testrl.c -o testrl -lreadline

См. Также этот вопрос

...