2013-02-21 1 views
0

입력을 허용하지 않는 scanf이 있습니다. 변수가 초기화되지 않은 경우에도 값은 자동으로 0입니다. 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를하는 도움이 될 것 같지 않습니다. 어떤 아이디어?

답변

6

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로 변경하고 명시 적으로 내 함수를 입력했습니다. 그러나 이제는 "상충되는 유형의보기", "이전의 암시 적 선언보기가 여기에있었습니다"등의 오류가 발생했습니다. –

+1

@CarlNathanMier : 아. C89 이전 버전에서는 컴파일러가 해당 함수에 대한 선행 선언없이 함수 호출을 확인하면 함수가'int'를 반환한다고 가정합니다. 그래서'main'에서'view'에 대한 호출을보고,'int'를 리턴한다고 가정하고,'view'에 대한 정의를 봅니다. 정의가'void'를 반환한다는 것을 제외하면, 그래서 가슴 앓이입니다. 함수를 사용하기 전에 선언해야합니다. 가장 쉬운 방법은 호출되기 전에 함수를 정의하는 것입니다. 이 경우,'main'의 정의를 다른 함수 정의 아래로 이동하십시오. –

+0

@ John Bode에게 감사 드려요.하지만 여전히'drop' 함수에서'scanf'와 같은 문제가 있습니다 ... –