"미친"이유는 다음과 같습니다. scanf
이 a
으로 숫자로 표시되지 않으므로으로 읽지 못할 경우 은이 파일 포인터를 넘기지 않습니다.
이것은 일반적으로 scanf
작업을 사용하지 않아야하는 한 가지 이유이며, 실패로 인해 파일 포인터가 불명확 한 위치에 남아있을 수 있습니다 (예 : 12 개 중 3 개에서만 스캔하는 경우).
다른 이유는 scanf
는 의미 "형식 검사"당신은 하드 사용자 입력에 비해 포맷되지 않은 더 아무것도 찾을 수 누르면 될 것입니다.
어쨌든, 실패로 돌아갑니다. 파일 포인터가 고급 상태가 아니기 때문에 다음에 다시 fscanf
을 실행하면 다시 a
(그리고 계속해서)을 읽으려고 시도합니다.
사용자 입력을 처리하기위한 괜찮은 기능을 원하는 경우
여기보다 더 봐 :
#include <stdio.h>
#include <string.h>
#define OK 0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
int ch, extra;
// Get line with buffer overrun protection.
if (prmpt != NULL) {
printf ("%s", prmpt);
fflush (stdout);
}
if (fgets (buff, sz, stdin) == NULL)
return NO_INPUT;
// If it was too long, there'll be no newline. In that case, we flush
// to end of line so that excess doesn't affect the next call.
if (buff[strlen(buff)-1] != '\n') {
extra = 0;
while (((ch = getchar()) != '\n') && (ch != EOF))
extra = 1;
return (extra == 1) ? TOO_LONG : OK;
}
// Otherwise remove newline and give string back to caller.
buff[strlen(buff)-1] = '\0';
return OK;
}
이 의지 입력 사용자로부터 라인을, (억제 할 "%s"
와 gets
또는 scanf
달리) 오버 플로우 보호.
입력이 너무 길면 줄 끝까지 플러시되므로 나머지 줄이 다음 입력 작업에 영향을 미치지 않습니다.
그런 다음 파일 포인터에 아무런 문제가없는 마음으로 버퍼 내용을 sscanf
에 저장할 수 있습니다.
다음 테스트 프로그램
이를 사용하는 방법을 보여줍니다 AS를
int main (void) {
int rc;
char buff[10];
rc = getLine ("Enter string> ", buff, sizeof(buff));
if (rc == NO_INPUT) {
// Extra NL since my system doesn't output that on EOF.
printf ("\nNo input\n");
return 1;
}
if (rc == TOO_LONG) {
printf ("Input too long [%s]\n", buff);
return 1;
}
printf ("OK [%s]\n", buff);
return 0;
}
를 제외하고, 유효한 크기의 방에 대한 귀하의 논리를 다시 검사 할 수 있습니다. 현재 가지고있는 방에서 7 피트 -42 피트로 입력 할 수 있습니다 :-)
입력시 특정 값으로 설정된 출력 값에 의존하는 것이 일반적으로 좋지 않습니다. 입력시 길이와 폭이 (예를 들어) 3과 4 인 경우이 함수는 사용자에게 입력을 요구하지 않고 바로 종료됩니다.
&&
대신 ||
을 사용하면 첫 번째 문제를 해결할 수 있습니다. 두 번째는 함수 시작시 변수를 0으로 초기화하여 루프가 입력되도록합니다.완성도를 들어
, 다음과 함께합니다 (include
진술과 getLine()
기능) 위의 원래 조각이 약간 get_room_size()
기능을 수정 한 것을 결합 할 경우 :
static void get_room_size(char room_id, int * length, int * width) {
char buff[100];
*length = *width = 0;
while ((*length <= 0) || (*width <= 0)) {
printf("Enter length and width of room %c in feet: ", room_id);
int rc = getLine (NULL, buff, sizeof (buff));
if (rc == NO_INPUT) {
printf ("\nEnd of file encountered.\n");
return;
}
if (rc == TOO_LONG) {
printf ("\nInput too long, please retry.\n");
continue;
}
if (sscanf(buff, "%d,%d", length, width) != 2) {
*length = *width = 0;
printf ("\nInput not in desired form (<number>,<number>), "
"please retry.\n");
continue;
}
if ((*length <=0) || (*width <= 0)) {
*length = *width = 0;
printf ("\nBoth length and width must be greater than zero, "
"please retry.\n");
}
}
}
과 매우 간단한 테스트 main()
를, 당신 ' 그것을하는 방법을 보여주는 완벽한 프로그램을 보게 될 것입니다.
int main (void) {
int len, wid;
get_room_size ('x', &len, &wid);
printf ("Length is %d, width is %d.\n", len, wid);
return 0;
}
을 읽을 방법
scanf()
성명에서 &을 넣어 말아 a '이므로 결코 읽히지 않습니다. –