Как можно сбросить входной поток в C?

Я не могу сбросить stdin здесь, есть ли способ сбросить его? Если не затем, как сделать getchar() взять символ в качестве входа от пользователя, вместо "\n", оставленного scanf() во входном буфере??

#include "stdio.h"
#include "stdlib.h"

int main(int argc,char*argv[]) {
    FILE *fp;
    char another='y';
    struct emp {
        char name[40];
        int age;
        float bs;
    };
    struct emp e;
    if(argc!=2) {
        printf("please write 1 target file name\n");
    }
    fp=fopen(argv[1],"wb");
    if(fp==NULL) {
        puts("cannot open file");
        exit(1);
    }
    while(another=='y') {
        printf("\nEnter name,age and basic salary");
        scanf("%s %d %f",e.name,&e.age,&e.bs);
        fwrite(&e,sizeof(e),1,fp);

        printf("Add another record (Y/N)");
        fflush(stdin);
        another=getchar();
    }
    fclose(fp);
    return 0;
}

Править: обновленный код, все еще не работая правильно

#include "stdio.h"
#include "stdlib.h"

int main(int argc,char*argv[]) {
    FILE *fp;
    char another='y';
    struct emp {
        char name[40];
        int age;
        float bs;
    };
    struct emp e;
    unsigned int const BUF_SIZE = 1024;
    char buf[BUF_SIZE];

    if(argc!=2) {
        printf("please write 1 target file name\n");
    }
    fp=fopen(argv[1],"wb");
    if(fp==NULL) {
        puts("cannot open file");
        exit(1);
    }
    while(another=='y') {
        printf("\nEnter name,age and basic salary : ");
        fgets(buf, BUF_SIZE, stdin);
        sscanf(buf, "%s %d %f", e.name, &e.age, &e.bs);
        fwrite(&e,sizeof(e),1,fp);
        printf("Add another record (Y/N)");
        another=getchar();
    }
    fclose(fp);
    return 0;
}

Вывод:

dev@dev-laptop:~/Documents/c++_prac/google_int_prac$ ./a.out emp.dat

Enter name,age and basic salary : deovrat 45 23
Add another record (Y/N)y

Enter name,age and basic salary : Add another record (Y/N)y

Enter name,age and basic salary : Add another record (Y/N)
5
задан red0ct 9 December 2019 в 11:00
поделиться

5 ответов

Обновление: вам нужно добавить еще один getchar () в конце цикла, чтобы использовать '\ n', следующее за Y / N. Я не думаю, что это лучший способ, но он заставит ваш код работать в том виде, в каком он есть сейчас.

while(another=='y') {
    printf("\nEnter name,age and basic salary : ");
    fgets(buf, BUF_SIZE, stdin);
    sscanf(buf, "%s %d %f", e.name, &e.age, &e.bs);
    fwrite(&e,sizeof(e),1,fp);
    printf("Add another record (Y/N)");
    another=getchar();
    getchar();
}

Я бы посоветовал прочитать данные, которые вы хотите проанализировать (до символа '\ n' включительно), в буфер, а затем проанализируйте его с помощью sscanf (). Таким образом, вы используете новую строку и можете выполнять другие проверки корректности данных.

8
ответ дан 18 December 2019 в 06:03
поделиться

fflush (stdin) - неопределенное поведение (a) . Вместо этого заставьте scanf «съесть» новую строку:

scanf("%s %d %f\n", e.name, &e.age, &e.bs);

Все остальные хорошо замечают, что scanf - плохой выбор. Вместо, следует использовать fgets и sscanf :

const unsigned int BUF_SIZE = 1024;
char buf[BUF_SIZE];
fgets(buf, BUF_SIZE, stdin);
sscanf(buf, "%s %d %f", e.name, &e.age, &e.bs);

(a) См., например, C11 7.21.5.2 Функция fflush :

int fflush (FILE * stream) - Если stream указывает на выходной поток или поток обновления, в котором не была введена самая последняя операция, функция fflush вызывает любые незаписанные данные для этого потока, которые должны быть доставлены в среду хоста для записи в файл; в противном случае поведение не определено.

10
ответ дан 18 December 2019 в 06:03
поделиться

Используйте это вместо getchar ():

   char another[BUF_SIZE] = "y";
   while( 'y' == another[0] )
   {
        printf( "\nEnter name,age and basic salary : " );
        fgets( buf, BUF_SIZE, stdin );
        sscanf( buf, "%s %d %f", e.name, &e.age, &e.bs );
        fwrite( &e, sizeof(e) , 1, fp );
        printf( "Add another record (Y/N)" );
        fgets( another, BUF_SIZE, stdin );
    }
3
ответ дан 18 December 2019 в 06:03
поделиться

Я бы порекомендовал fgets () + sscanf () подход, который предлагали многие другие люди. Вы также можете использовать scanf ("% * c"); перед вызовом getchar () . Это по сути съест персонажа.

2
ответ дан 18 December 2019 в 06:03
поделиться

Не рекомендуется использовать fflush (stdin), поскольку он имеет неопределенное поведение. Как правило, такие функции, как scanf (), оставляют завершающие символы новой строки в stdin. Так что лучше использовать функции «чище», чем scanf (). Вы можете заменить scanf () комбинацией fgets () и sscanf (), а можете отказаться от fflush (stdin).

2
ответ дан 18 December 2019 в 06:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: