[c] C에서 입력 버퍼를 지우는 방법은 무엇입니까?

다음 프로그램이 있습니다.

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캐릭터?

다음으로 저자는 이러한 문제를 해결하는 두 가지 방법을 제안했습니다.

  1. 사용하다 fflush()

  2. 다음과 같은 함수를 작성하십시오.

    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에서 다시 참조).

기본적으로 유일한 이식 가능한 접근 방식은 다음과 같습니다.

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이어야합니다 .intEOF

현재 줄 뒤에 줄이 더 있는지 알아내는 이식 가능한 방법은 없습니다 (없으면 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에서 거의 새롭지 않습니다.

누군가에게 도움이되기를 바랍니다