Я не могу сбросить 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)
Обновление: вам нужно добавить еще один 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 (). Таким образом, вы используете новую строку и можете выполнять другие проверки корректности данных.
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 вызывает любые незаписанные данные для этого потока, которые должны быть доставлены в среду хоста для записи в файл; в противном случае поведение не определено.
Используйте это вместо 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 );
}
Я бы порекомендовал fgets ()
+ sscanf ()
подход, который предлагали многие другие люди. Вы также можете использовать scanf ("% * c");
перед вызовом getchar ()
. Это по сути съест персонажа.
Не рекомендуется использовать fflush (stdin), поскольку он имеет неопределенное поведение. Как правило, такие функции, как scanf (), оставляют завершающие символы новой строки в stdin. Так что лучше использовать функции «чище», чем scanf (). Вы можете заменить scanf () комбинацией fgets () и sscanf (), а можете отказаться от fflush (stdin).