即使使用fflush,也会跳过scanf
问题描述:
我有一个不接受输入的scanf
。即使该变量未被初始化,该值也会自动为零。该scanf
跳过:即使使用fflush,也会跳过scanf
printf("\nEnter the number of the student to be dropped: ");
fflush(stdin);
scanf(" %d ",&choice);
printf("choice is %d", choice);
当程序运行时,它立即显示“选择为0”。
的片段上方从下拉()函数在这个代码采取:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student{
char name[50];
char* course;
};
main()
{
char repeat;
do{
system("cls");
int mainchoice;
printf("Student Enrollment System");
printf("\n");
printf("\n");
printf("1. View\n");
printf("2. Enroll\n");
printf("3. Drop enrollment\n");
printf("Select choice: ");
fflush(stdin);
scanf("%d",&mainchoice);
system("cls");
switch(mainchoice){
case 1:
view();
break;
case 2:
enroll();
break;
case 3:
drop();
break;
default:
printf("Please enter a valid number.");
getch();
fflush(stdin);
break;
}
printf("\nWould you like to make another transaction? [Y/N]: ");
fflush(stdin);
scanf("%c",&repeat);
}while(repeat=='Y'||repeat=='y');
}
view(){
int ctr = count();
printf("Enrolled Students:\n\n");
system("type records.txt");
printf("\n\nNumber of students enrolled: %d", ctr);
getch();
fflush(stdin);
}
enroll(){
int choice;
char validate;
printf("1. Information Technology\n");
printf("2. Computer Science\n");
printf("3. Computer Engineering\n");
printf("4. Information Systems\n");
struct student news;
printf("Name: ");
fflush(stdin);
gets(news.name);
printf("Course Number: ");
fflush(stdin);
scanf("%d", &choice);
switch(choice){
case 1:
news.course = "BSIT";
break;
case 2:
news.course= "BSCS";
break;
case 3:
news.course = "BSCpE";
break;
case 4:
news.course = "BSIS";
break;
default:
printf("Please enter a valid number\n");
break;
}
printf("Enroll %s to %s? [Y/N]:",news.name,news.course);
fflush(stdin);
scanf("%c", &choice);
if(choice=='Y' || choice=='y')
{
FILE * records;
records = fopen("records.txt", "a+");
fprintf(records, "%s, %s\n",news.name,news.course);
fclose(records);
printf("%s has been enrolled to %s\n",news.name, news.course);
}
else
{
printf("You have chosen to cancel your transaction");
}
}
drop(){
printf("Drop Student:\n\n");
int ctr = 0;
int choice; //which student to delete
char c;
FILE * record; // original records.txt
FILE* repo; //temporary data storage
record = freopen("records.txt", "r", stdin);
while((c = fgetchar())!=EOF){
if(c == '\n'){
}
else{
ctr=ctr+1;
printf("%d. ", ctr);
while(1){
printf("%c",c);
c= fgetchar();
if(c=='\n'){
printf("%c",c);
break;
}
}
}
}
fclose(record);
fflush(stdin);
fflush(stdin);
printf("\nEnter the number of the student to be dropped: ");
fflush(stdin);
scanf(" %d ",&choice);
getch();
getch();
fflush(stdin);
ctr = 1;
fflush(stdin);
repo = fopen("temp.txt","w");
record = freopen("records.txt","r",stdin);
while((c = getchar()) != EOF){
if(c == '\n'){
}
else{
while(ctr!=choice){
fprintf(repo,"%c",c);
c= fgetchar();
if(c=='\n'){
fprintf(repo,"%c",c);
ctr = ctr + 1;
break;
}
}
}
}
fclose(record);
fclose(repo);
getch();
}
//counts the number of rows in the record
int count(){
int ctr=0;
char c;
FILE * records;
records = freopen("records.txt","r", stdin);
if(records!=NULL){
while((c=fgetchar()) !=EOF){
if(c=='\n'){
ctr = ctr+1;
}
}
}
fclose(records);
return ctr;
}
做fflush
似乎并没有帮助。有任何想法吗?
答
fflush
的行为没有为输入流定义; fflush(stdin)
是一个编码错误,您应该从您的代码中删除这些调用。
扫描单个字符时,在%c
转换说明符之前添加一个空格;这将告诉scanf
跳过任何前导空格和读取下一个非空白字符:
scanf(" %c", &choice);
的%d
和%s
转换说明将跳过任何前导空格。
编辑
隐式类型不再支持为C99的,这是一个坏习惯进入。显式键入功能,并使用void
作为参数列表来指定,他们不接受参数:
main() => int main(void)
view() => void view(void) // void since it isn't returning a value
drop() => void drop(void)
等
同样,gets
在C99取消,并完全消失为2011标准。使用它将在您的程序中引入故障点/主要安全漏洞。改为使用fgets
。
谢谢,我做了你告诉我的。改变了选择的数据类型为char,并显式地键入了我的函数,但是现在我得到了诸如“视图类型冲突”,“以前的隐式声明在这里等等”的错误......等等...... – 2013-02-21 04:23:18
@CarlNathanMier:啊。在C89和更早的版本中,如果编译器看到一个没有该函数的前面声明的函数调用,它将假定该函数返回'int'。所以它看到'main'中的'view'的调用,假定它返回一个'int',然后它看到'view'的定义,除了现在定义说它返回'void',因此是胃灼热。使用前需要声明函数;最简单的方法是在函数调用之前定义函数。在这种情况下,将'main'的定义移动到其他函数定义的下面。 – 2013-02-21 04:31:57
谢谢@John Bode,但我仍然遇到'drop'函数中'scanf'的问题... – 2013-02-21 05:05:11