scanf()는 사용자의 입력을 특정 형식(format string)에 맞춰 읽은 뒤 변수에 값을 저장한다. 이 형식(format string)에는 일반적인 문자(ex. a, b, c, 공백 등)나 변환 문자(conversion specification)가 들어갈 수 있는데 어떤 값이 들어가느냐에 따라 작동하는 방법이 다르다.
format string이 변환 문자로만 구성된 경우
아래와 같이 scanf의 format string이 변환 문자로만 구성된 경우를 살펴보겠다.
scanf("%d%f", &intValue, &floatValue);
이런 경우 scanf()는 다음과 같은 순서로 작동한다.
- 사용자로부터 들어온 input string(string type)을 format string과 왼쪽부터 비교한다.
- 제일 처음 시작되는 공백은 무시하고 input character를 하나씩 읽으며 변환 문자(%d, %f)와 비교한다.
- 해당 변환 문자가 input character를 읽을 수 있다면 다음 input character를 변환 문자와 비교.
만약 해당 변환 문자가 input character를 읽을 수 없는 경우 다음 변환 문자와 input character를 비교(다음 변환 문자가 없을 경우 다음 scanf 함수가 호출될 때 비교) - 해당 변환 문자가 읽을 수 없는 형식으로 input string이 들어오면 함수를 return(뒤에 위치한 나머지 변환 문자는 값을 읽을 수 없음)
그리고 %d(Integer type)와 %f(floating-point type)가 읽을 수 있는 형식은 아래와 같다.
- Integer type
- 첫 번째 문자로는 (숫자, +, -)만 가능하다
- 그 이후로는 오직 숫자만 가능하다
- Floating-point type
- 첫 번째 문자가 (+, -)로 시작하는지 확인, 시작하면 읽음(꼭 시작할 필요는 없음)
- 그 이후로는 (숫자, 소수점, 지수(e, E))만 가능하다
예를 들어 다음과 같은 scanf()가 있을 때 input으로 [1-20.3-4]가 들어오면 scanf는 다음과 같이 동작한다.
#include <stdio.h>
int main(int argc, char* argv[]) {
int i1,i2;
float f1,f2;
scanf("%d%d%f%f", &i1, &i2, &f1, &f2); // 1-20.3-4
printf("%d %d %.1f %.1f\n", i1, i2, f1, f2); //1 -20 0.3 -4.0
return 0;
}
- input string의 제일 처음 값 [1]을 첫 번째 변환 문자 %d(i1에 해당)가 읽을 수 있는지 확인(가능) - 진행
- input string의 두 번째 값 [-]를 %d가 읽을 수 있는지 확인(%d는 오직 첫 번째로 들어온 [-]만 읽을 수 있고 이미 1이 들어온 상태이기 때문에 읽을 수 없음) - 읽지 않고 멈춤
- 두 번째 변환 문자 %d(i2에 해당)가 앞에서 읽지 못한 [-]를 읽을 수 있는지 확인(%d는 첫 번째 문자로 [-]를 읽을 수 있기에 가능) - 진행
- [2]를 읽을 수 있는지 학인(가능) - 진행
- [0]을 읽을 수 있는지 확인(가능) - 진행
- [.]을 읽을 수 있는지 확인(불가능) - 읽지 않고 멈춤
- 세 번째 변환 문자 %f(f1에 해당)가 [.]을 읽을 수 있는지 확인(가능) - 진행
- [3]을 읽을 수 있는지 확인(가능) - 진행
- [-]를 읽을 수 있는지 확인(불가능) - 읽지 않고 멈춤
- 네 번째 변환 문자 %f(f2에 해당)가 [-]를 읽을 수 있는지 확인(가능) - 진행
- [4]를 읽을 수 있는지 확인(가능) - 진행
- 제일 마지막 줄 바꿈 [\n]을 읽을 수 있는지 확인(불가능) - 읽지 않고 멈춤
위와 같은 과정을 통해 (i1, i2, f1, f2)는 각각 (1, -20, 0.3, -4)의 값을 가지고 마지막 줄 바꿈 '\n'은 읽어지지 않은 채 input buffer에 남아 다음 scanf가 실행될 때 처리된다.
format string에 일반 문자가 포함되어 있는 경우
공백이 포함되어 있는 경우
format string에 한 개 또는 여러 개의 공백이 포함되어 있는 경우 input character와 format string 공백을 비교할 때 공백이 아닌 문자가 들어올 때까지 계속 읽는다. 이때 input charater의 공백의 개수는 상관이 없다. 즉 format string에 공백이 있는 경우 input string 상의 0~무한개까지의 공백과 매칭이 된다.
아래와 같은 경우 입력으로 들어오는 1과 -2 사이 공백이 몇 개든 상관이 없다.
#include <stdio.h>
int main(int argc, char* argv[]) {
int i1,i2;
scanf("%d %d", &i1, &i2);
printf("%d %d\n", i1, i2);
return 0;
}
/*
Result
입력
1-2
출력
1 -2
입력
1 -2
출력
1 -2
입력
1 -2
출력
1 -2
입력
1
-2
출력
1 -2
*/
공백 이외의 문자가 포함되어 있는 경우
format string에 공백 이외의 문자가 포함되어 있는 경우 input character와 비교할 때 fomat string 문자가 input character와 일치하면 입력 과정을 계속 진행시키고 없으면 scanf를 종료시킨다.
#include <stdio.h>
int main(int argc, char* argv[]) {
int i1, i2 = -1;
scanf("%d/%d", &i1, &i2);
printf("%d %d\n", i1, i2);
return 0;
}
/*
Result
입력
1/2
출력
1 2
입력
1 2
출력
1 -1 // i2는 읽어지지 않고 종료됨
입력
1%2
출력
1 -1 // i2는 읽어지지 않고 종료됨
*/
출처
- K. N. King, 『C Programming : A Modern Approach, 2/E』, W. W. Norton & Company(2008), p42-46.
'개인공부 > C, C++' 카테고리의 다른 글
[C] GCC와 CC의 차이점 (2) | 2021.02.12 |
---|---|
[C/C++] 지역변수/static 지역변수/전역변수 차이점(storage duration, scope) (0) | 2021.01.26 |
[C/C++] C언의 강점과 약점 (0) | 2021.01.10 |
댓글