即使使用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

+0

谢谢,我做了你告诉我的。改变了选择的数据类型为char,并显式地键入了我的函数,但是现在我得到了诸如“视图类型冲突”,“以前的隐式声明在这里等等”的错误......等等...... – 2013-02-21 04:23:18

+1

@CarlNathanMier:啊。在C89和更早的版本中,如果编译器看到一个没有该函数的前面声明的函数调用,它将假定该函数返回'int'。所以它看到'main'中的'view'的调用,假定它返回一个'int',然后它看到'view'的定义,除了现在定义说它返回'void',因此是胃灼热。使用前需要声明函数;最简单的方法是在函数调用之前定义函数。在这种情况下,将'main'的定义移动到其他函数定义的下面。 – 2013-02-21 04:31:57

+0

谢谢@John Bode,但我仍然遇到'drop'函数中'scanf'的问题... – 2013-02-21 05:05:11