[c] scanf ()는 버퍼에 새 줄 문자를 남깁니다.

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

int main(int argc, char *argv[])
{
  int a, b;
  char c1, c2;
  printf("Enter something: ");
  scanf("%d",&a); // line 1
  printf("Enter other something: ");
  scanf("%d", &b); // line 2

  printf("Enter a char: ");
  scanf("%c",&c1); // line 3
  printf("Enter another char: ");
  scanf("%c", &c2); // line 4

  printf("Done"); // line 5

  system("PAUSE");

  return 0;
}

내가 C 책을 읽었을 때 저자는 scanf()버퍼에 줄 바꿈 문자 를 남겼으므로 프로그램은 사용자가 데이터를 입력하기 위해 줄 4에서 멈추지 않고 새 줄 문자를 c2에 저장하고 다음으로 이동합니다. 5 행.

맞습니까?

그러나 이것은 char데이터 유형 에서만 발생 합니까? int1, 2, 3 행에서 와 같이 데이터 유형에 대해이 문제를 보지 않았기 때문입니다. 맞습니까?



답변

scanf()함수는 문자 이외의 변환을 구문 분석하기 전에 자동으로 선행 공백을 건너 뜁니다. 문자 형식 (주로 %c, 스캔 세트 %[…]— 및 %n)은 예외입니다. 공백을 건너 뛰지 않습니다.

" %c"선택적 공백을 건너 뛰려면 선행 공백과 함께 사용하십시오 . scanf()형식 문자열 에 후행 공백을 사용하지 마십시오 .

이것은 여전히 ​​입력 스트림에 남아있는 후행 공백을 사용하지 않으며 행 끝까지도 사용하지 않으므로 동일한 입력 스트림을 사용 getchar()하거나 사용하는 경우에도주의하십시오 fgets(). 우리는 변환 전에 공백을 건너 뛰도록 scanf를 받고 %d있습니다.


리터럴 텍스트와 같이 변환 이외의 공백이 아닌 “지시문”( POSIX scanf 용어 사용 ) scanf("order = %d", &order);은 공백도 건너 뛰지 않습니다. 리터럴 order은 읽을 다음 문자와 일치해야합니다.

따라서 " order = %d"이전 줄에서 줄 바꿈을 건너 뛰고 싶지만 여전히이 질문과 같이 고정 문자열에 대한 리터럴 일치가 필요한 경우 거기를 원할 것입니다 .


답변

사용 scanf(" %c", &c2);. 이것은 당신의 문제를 해결할 것입니다.


답변

여기 에서 얻은 또 다른 옵션 은 할당 억제 옵션 을 사용하여 개행을 읽고 버리는 입니다. 이를 위해, 우리는 단지 사이 별표 문자 읽기 형식을 넣어 %c:

scanf("%d%*c",&a); // line 1
scanf("%c%*c",&c1); // line 3

scanf 그런 다음 다음 문자 (즉, 개행)를 읽지 만 포인터에 할당하지 않습니다.

그러나 결국 에는 FAQ의 마지막 옵션을 두 번째로하겠습니다 .

또는 요구 사항에 따라 scanf () / getchar ()를 잊어 버리고 fgets ()를 사용하여 사용자로부터 텍스트 줄을 가져와 직접 구문 분석 할 수도 있습니다.


답변

getchar()두 번째 호출 전에 사용하십시오 scanf().

scanf("%c", &c1);
getchar();  // <== remove newline
scanf("%c", &c2);


답변