다음 프로그램이 있습니다.
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
데이터 유형 에서만 발생 합니까? int
1, 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);