Я делаю поспешные выводы, но я предполагаю, что вы хотите получить полную дату, а не только «10» дня?
gawk -F'|' '{print gensub( /^(.{8}).*/, "\\1", "1",$5)}' data
20190110
20190110
20190110
20190110
Решение: необходимо добавить fflush(stdin);
, когда 0
возвращается от scanf
.
Причина: Это, кажется, оставляет входной символ в буфере, когда с ошибкой встречаются, таким образом, каждый раз scanf
называют им, просто продолжает пытаться обработать недопустимый символ, но никогда не удалять его формируют буфер. Когда Вы будете звонить fflush
, входной буфер (stdin) будет очищен так, недопустимый символ больше не будет обрабатываться повторяемо.
Вы Программируете Измененный: Ниже Ваша программа, измененная с необходимым изменением.
#include <stdio.h>
int main()
{
int number, p = 0, n = 0;
while (1) {
printf("-> ");
if (scanf("%d", &number) == 0) {
fflush(stdin);
printf("Err...\n");
continue;
}
if (number > 0) p++;
else if (number < 0) n++;
else break; /* 0 given */
}
printf("Read %d positive and %d negative numbers\n", p, n);
return 0;
}
scanf
использует только ввод, который соответствует строке формата, возвращая количество использованных символов. Любой символ, который не соответствует строке формата, вызывает остановку сканирования и оставляет недопустимый символ в буфере. Как говорили другие, вам все равно нужно очистить недопустимый символ из буфера, прежде чем продолжить. Это довольно грязное исправление, но оно удалит неправильные символы из вывода.
char c = '0';
if (scanf("%d", &number) == 0) {
printf("Err. . .\n");
do {
c = getchar();
}
while (!isdigit(c));
ungetc(c, stdin);
//consume non-numeric chars from buffer
}
edit: исправлен код, чтобы удалить все нечисловые символы за один раз. Больше не будет выводить несколько ошибок "Errs" для каждого нечислового символа.
Здесь довольно хороший обзор scanf.
Вместо того, чтобы использовать scanf ()
и иметь дело с буфером, имеющим недопустимый символ, используйте fgets ()
и sscanf ()
.
/* ... */
printf("0 to quit -> ");
fflush(stdout);
while (fgets(buf, sizeof buf, stdin)) {
if (sscanf(buf, "%d", &number) != 1) {
fprintf(stderr, "Err...\n");
} else {
work(number);
}
printf("0 to quit -> ");
fflush(stdout);
}
/* ... */
Очистите входной буфер перед сканированием:
while(getchar() != EOF) continue;
if (scanf("%d", &number) == 0) {
...
Я собирался предложить fflush (stdin)
, но, по-видимому, это приводит к неопределенному поведению .
В ответ на ваш комментарий, если вы хотите, чтобы появилось приглашение, вы должны сбросить выходной буфер. По умолчанию это происходит только при печати новой строки. Например:
while (1) {
printf("-> ");
fflush(stdout);
while(getchar() != EOF) continue;
if (scanf("%d", &number) == 0) {
...
Из-за проблем с scanf
, указанных в других ответах, вам действительно стоит подумать об использовании другого подхода. Я всегда считал scanf
слишком ограниченным для серьезного чтения и обработки ввода. Лучше просто читать целые строки с помощью fgets
, а затем работать с ними с помощью таких функций, как strtok
и strtol
(которые, кстати, будут правильно анализировать целые числа и сообщать вы именно там, где начинаются недопустимые символы).
scanf ()
оставляет « a
» во входном буфере для следующего раза. Вероятно, вам следует использовать getline ()
, чтобы прочитать строку независимо от того, что она делает, а затем проанализировать ее с помощью strtol ()
или подобного.
(Да, getline ()
относится к GNU, а не к POSIX. И что? Вопрос помечен как «gcc» и «linux».
Я думаю, вам просто нужно очистить буфер, прежде чем продолжить цикл. Что-то вроде этого, вероятно, сработает, хотя я не могу проверить то, что пишу отсюда:
int c;
while((c = getchar()) != '\n' && c != EOF);