2013-01-29 2 views
1

루프를 사용하여 1-5 사이의 입력을 받아야합니다. 다른 입력을 받으면 1-5를 얻을 때까지 반복해야합니다.C에 문자가 입력되면 루프를 종료하는 방법은 무엇입니까?

내가 뭘 잘못하고 있는지 말해 줄 수 있겠 니? 내 코드의

부 :

int rateSelected, weeklyHours; 

    printf("Enter the number corresponding to the desired pay rate or action:\n"); 
    printf("1) %.2lf$/hr        2) %.2lf$/hr\n", RATE1, RATE2); 
    printf("3) %.2lf$/hr        4) %.2lf$/hr\n", RATE3, RATE4); 
    printf("5) Quit\n"); 

    while ((scanf("%d", &rateSelected)) != EOF && rateSelected != 5) 
    { 
     if (rateSelected > 5 || isalpha(rateSelected) ==1){ 
      printf("please enter a number between 1-5:\n"); 
     continue; 
     } 

     printf("Now enter your weekly hours:\n"); 
     scanf("%d", &weeklyHours); 
     ChoosePayRate(rateSelected, weeklyHours); 
    } 

TNX

+0

int e; while ((e = scanf("%d", &rateSelected)) != EOF) { scanf("%*[^\n]"); // this clean your input buffer if (e==0 || rateSelected>5 || rateSelected<1) { printf("please enter a number between 1-5:\n"); continue; } 

-5 '상태에서'rateSelected <1 '도 확인해야합니다. – Constantin

+2

누군가가 문자를 입력하면'scanf ("% d", & rateSelected)'가 실패하고, 0을 리턴하고 (! = EOF') _ 다음 입력을 위해 buffer_에 잘못된 입력을 남긴다. 무한 루프 'rateSelected'가 값을 가지지 않는 한 5). –

답변

2

문제는 %d 형식 지정자를 사용하는 것입니다. 숫자 대신 문자를 입력하면 scanf은 아무 것도 읽지 않음을 나타 내기 위해 0을 반환합니다. 숫자와 함께 문자를 입력 할 수있게하려면 scanf이 0을 반환 할 때 문자열 읽기를 추가하거나 문자열 버퍼를 항상 읽은 다음 sscanf 또는 atoi을 사용하여 문자열을 정수로 변환해야합니다. 에 int를 저장하기 때문에

0

isalpha(rateSelected)를 제거합니다.

isalpha()은 매개 변수로 전달 된 값이 영숫자 문자인지 확인하지만 방금 읽은 값인 int을 전달합니다.

그러나, 이것은 여전히 ​​충분하지 않습니다 - 당신이 scanf()이 실제로 int을 읽기 있는지 확인하는 scanf()에서 반환 값을 잡을 필요가있다. 그러나 int가 입력되지 않으면 문자는 무시되지 않으므로 다음 scanf()가 다시 변환하려고 시도하므로 무한 루프가 발생합니다. @dasblinkenlight에서 제공하는 솔루션을 사용하는 것이 더 좋습니다.

0

isalpha(rateselected)이 절대로 안됩니다. scanf("%d",rateselected)은 이미 문자 입력 포착을 처리하고이 경우 0을 반환합니다. 따라서 isalpha 테스트를 rateselected == 0 테스트로 변경해야합니다.

또한 scanf는 절대로 EOF를 반환하지 않습니다. 0을 반환하면 feof(stdin)을 테스트하여 실제로 입력이 끝나는 지 확인해야합니다. (키보드 입력의 경우 ctrl-Z에 해당).

+1

정확하지 않습니다. 사실'isalpha()'는'int'와 함께 작동합니다. '% d' 형식 지정자를 만난'scanf()'는 입력이 정수가 아닌 경우 변환하지 않습니다. –

+1

. 'isalpha()'는 입력 값이 ASCII 문자에 해당하는지 테스트합니다. 하지만 scanf (% d)는 문자를 만날 때 ascii 값을 생성하지 않으므로 거부합니다. – AShelly

0

이 경우 fgets()strtol()을 사용하는 것이 좋습니다. scanf와 및 stdio의 라인 버퍼링이 ... 함께 매우 도움이되지 않습니다

char line[LINE_MAX]; 
do { 
    fgets(line, sizeof(line), stdin); 
} while(!isdigit(line[0])); 
int choice = strtol(line, NULL, 10); 
+0

감사합니다. 불행히도 나는 책에서 아직 fgets를 얻지 못했고, 운동은 scanf를 사용하여 요구된다. @ H2CO3 – MNY

+0

@ user1959174 그건 불평이없는 일이다. 일반적으로'scanf()'는 피해야한다. 그것이 무엇을하는지 정확히 모르는 경우 opengroups.org에서 문서를 찾으십시오. –

0

사용이 : 입력 1 사이 '로되어있는 경우 대신

while ((scanf("%d", &rateSelected)) != EOF && rateSelected != 5) 
    { 
     if (rateSelected > 5 || isalpha(rateSelected) ==1){ 
      printf("please enter a number between 1-5:\n"); 
     continue; 
     } 
+0

나는 그것을 대체하려고했지만 편지를 입력하면 "1-5 사이의 숫자를 입력하십시오."라는 메시지가 나타납니다. @ MohamedKALLEL – MNY

+0

@DanielFischer의 의견보기 –

+0

@ user1959174 코드를 업데이트했습니다.'scanf "% * [^ \ n]");'각 scanf ("% d") 이후에 버퍼를 지우려면; – MOHAMED

관련 문제