다음 프로그램이 있습니다.
int main(int argc, char *argv[])
{
char ch1, ch2;
printf("Input the first character:"); // Line 1
scanf("%c", &ch1);
printf("Input the second character:"); // Line 2
ch2 = getchar();
printf("ch1=%c, ASCII code = %d\n", ch1, ch1);
printf("ch2=%c, ASCII code = %d\n", ch2, ch2);
system("PAUSE");
return 0;
}
위 코드의 작성자가 설명했듯이 프로그램이 제대로 작동하지 않습니다. 첫 번째 줄에서 사용자가 Enter 키를 누르면 입력 버퍼 2 문자 Enter key (ASCII code 13)
및 \n (ASCII code 10)
. 따라서 2 행에서를 읽고 \n
사용자가 문자를 입력 할 때까지 기다리지 않습니다.
알겠습니다. 하지만 내 첫 번째 질문은 : 두 번째 이유는 getchar()
( ch2 = getchar();
) 읽기하지 않는 Enter key (13)
것이 아니라, \n
캐릭터?
다음으로 저자는 이러한 문제를 해결하는 두 가지 방법을 제안했습니다.
-
사용하다
fflush()
-
다음과 같은 함수를 작성하십시오.
void clear (void) { while ( getchar() != '\n' ); }
이 코드는 실제로 작동했습니다. 하지만 어떻게 작동하는지 스스로 설명 할 수 없습니까? while 문에서를 사용하므로 ?를 getchar() != '\n'
제외한 모든 단일 문자를 읽습니다 '\n'
. 그렇다면 입력 버퍼에 여전히 '\n'
문자 가 남아 있습니까?
답변
라인 1에서 사용자가 Enter 키를 누르면 입력 버퍼 2 문자 인 Enter 키 (ASCII 코드 13) 및 \ n (ASCII 코드 10)에 남아 있으므로 프로그램이 제대로 작동하지 않습니다. 따라서 2 행에서 \ n을 읽고 사용자가 문자를 입력 할 때까지 기다리지 않습니다.
2 행에서 보는 동작은 정확하지만 정확한 설명은 아닙니다. 텍스트 모드 스트림에서는 플랫폼에서 사용하는 줄 끝 (캐리지 리턴 (0x0D) + 줄 바꿈 (0x0A), 베어 CR 또는 베어 LF)이 무엇인지는 중요하지 않습니다. C 런타임 라이브러리가이를 처리합니다. 프로그램은 '\n'
개행 문자 만 볼 것 입니다.
문자를 입력하고 Enter 키를 누르면 해당 입력 문자를 1 행에서 읽은 다음 '\n'
2 행 에서 읽습니다. Y / N 응답을 읽는 데 사용 scanf %c
하고 있지만 나중에 입력을 건너 뜁니다. comp.lang.c FAQ에서.
제안 된 솔루션에 대해서는 다음을 참조하십시오 (comp.lang.c FAQ에서 다시 참조).
- 다음 프롬프트에서 사용자의 자동 완성 기능이 읽히지 않도록 보류중인 입력을 어떻게 플러시 할 수 있습니까? 윌
fflush(stdin)
작동? - 경우에
fflush
의지하지 작업, 나는 플러시 입력에 무엇을 사용할 수 있습니까?
기본적으로 유일한 이식 가능한 접근 방식은 다음과 같습니다.
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
당신의 getchar() != '\n'
당신이 전화를 한 번 때문에 루프 작동 getchar()
, 반환 된 캐릭터가 이미 입력 스트림에서 제거되었습니다.
또한, 나는 당신이 scanf
완전히 사용하는 것을 막아야 할 의무가 있다고 느낍니다 . 왜 모든 사람들이 사용하지 말라고 말하는가 scanf
? 대신 무엇을 사용해야합니까?
답변
다음과 같이 할 수도 있습니다.
fseek(stdin,0,SEEK_END);
답변
이미 부분적으로 읽으려고 한 줄의 끝까지 정리하는 이식 가능한 방법은 다음과 같습니다.
int c;
while ( (c = getchar()) != '\n' && c != EOF ) { }
이것은 \n
파일의 끝을 알릴 때까지 문자를 읽고 버립니다 . 또한 EOF
입력 스트림이 줄이 끝나기 전에 닫히는 경우를 확인합니다 . 값을 보유하려면 의 유형이 (또는 그 이상) c
이어야합니다 .int
EOF
현재 줄 뒤에 줄이 더 있는지 알아내는 이식 가능한 방법은 없습니다 (없으면 getchar
입력을 차단합니다).
답변
선:
int ch;
while ((ch = getchar()) != '\n' && ch != EOF)
;
줄 바꿈 ( '\n'
) 앞의 문자 만 읽지 않습니다 . 다음 줄 바꿈 (또는 EOF가 발견됨 ) 까지 스트림의 모든 문자를 읽고 삭제합니다 . 테스트가 참이 되려면 먼저 줄 바꿈을 읽어야합니다. 따라서 루프가 중지되면 줄 바꿈은 마지막으로 읽은 문자이지만 읽은 것입니다.
캐리지 리턴 대신 라인 피드를 읽는 이유는 시스템이 리턴을 라인 피드로 변환했기 때문입니다. 엔터를 누르면 라인의 끝을 알립니다 …하지만 스트림에는 시스템의 일반 라인 끝 마커이기 때문에 대신 라인 피드가 포함됩니다. 플랫폼에 따라 다를 수 있습니다.
또한 fflush()
입력 스트림 에서 사용 하는 것이 모든 플랫폼에서 작동하는 것은 아닙니다. 예를 들어 일반적으로 Linux에서는 작동하지 않습니다.
답변
하지만 어떻게 작동하는지 스스로 설명 할 수 없습니까? while 문에서를 사용하므로 ??를
getchar() != '\n'
제외한 모든 단일 문자를 읽습니다'\n'
. 그렇다면 입력 버퍼에 여전히'\n'
문자 가 남아 있습니까 ??? 내가 뭔가를 오해하고 있습니까 ??
인식하지 못할 수있는 것은 입력 버퍼에서 문자를 제거한 후에 비교가 발생한다는 것입니다 getchar()
. 당신이 도달했을 때 그래서 '\n'
,이 소비되고 다음 당신은 루프의 탈출.
답변
당신은 시도 할 수 있습니다
scanf("%c%*c", &ch1);
% * c는 개행을 허용하고 무시합니다.
정의되지 않은 동작을 호출하는 fflush (stdin) 대신 작성할 수있는 메서드가 하나 더 있습니다.
while((getchar())!='\n');
while 루프 뒤에 세미콜론을 잊지 마세요.
답변
솔루션을 구현하는 데 문제가 발생했습니다.
while ((c = getchar()) != '\n' && c != EOF) { }
같은 문제가있는 사람을 위해 약간의 조정 ‘코드 B’를 게시합니다.
문제는 프로그램이 입력 문자와는 별개로 ‘\ n’문자를 계속 잡았다는 것입니다. 여기에 문제를 준 코드가 있습니다.
코드 A
int y;
printf("\nGive any alphabetic character in lowercase: ");
while( (y = getchar()) != '\n' && y != EOF){
continue;
}
printf("\n%c\n", toupper(y));
그리고 조정은 while 루프의 조건이 평가되기 직전에 (n-1) 문자를 ‘catch’하는 것이 었습니다. 다음은 코드입니다.
코드 B
int y, x;
printf("\nGive any alphabetic character in lowercase: ");
while( (y = getchar()) != '\n' && y != EOF){
x = y;
}
printf("\n%c\n", toupper(x));
가능한 설명은 while 루프가 중단 되려면 변수 y에 ‘\ n’값을 할당해야하므로 마지막으로 할당 된 값이됩니다.
설명, 코드 A 또는 코드 B와 함께 뭔가를 놓친 경우 나에게 말 해주세요, 나는 c에서 거의 새롭지 않습니다.
누군가에게 도움이되기를 바랍니다