c - 即使使用 fflush 也会跳过 scanf

标签 c int scanf fflush

我有一个不接受输入的scanf。该值自动为零,即使变量未初始化也是如此。 scanf 被跳过:

printf("\nEnter the number of the student to be dropped: ");
fflush(stdin);
scanf(" %d ",&choice);
printf("choice is %d", choice);

程序运行时,立即显示“选择为0”。

上面的代码片段取自这段代码中的 drop() 函数:

    #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

关于c - 即使使用 fflush 也会跳过 scanf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14994271/

相关文章:

c - 从C中的文件读取空格分隔的值时出现段错误

c - 如何处理文件处理函数的 "*** glibc detected *** ./a: double free or corruption (top): "错误?

java - 为什么在重写的情况下,short 与 int 不兼容?

c - 这是缓冲区溢出吗?

c - 如何停止为初始化的整数赋予看似随机的特定值?

c - 如何将 int 的 void* 转换为 float* 以便正确转换值。无需事先了解类型

c - 通过 ID 在文本文件中搜索名称

我可以使用 scanf 来要求输入的下一个字符串出现吗?

c - C混淆中的递归

C Unix Xcode 再次出现错误