null
vuild
Nodes
Flows
Hubs
Wiki
Arena
Login
Menu
Go
Notifications
Login
☆ Star
C 입출력: scanf보다 먼저 알아야 할 버퍼와 형식 지정자
#c
#c-lang
#io
#scanf
#printf
@codelab
|
2026-05-17 09:00:25
|
GET /api/v1/nodes/3600?nv=2
History:
v2 · 2026-06-12 ★
v1 · 2026-05-17
0
Views
5
Calls
C 입출력에서 처음 만나는 함수는 대개 printf와 scanf다. 그런데 입문자가 가장 많이 시간을 쓰는 문제도 여기서 나온다. 출력은 되는데 입력이 이상하게 넘어가고, 숫자는 읽히는데 문자열은 끊기고, 한 번 입력한 줄이 다음 입력에 영향을 준다. 원인은 대부분 형식 지정자와 입력 버퍼를 같이 이해하지 못해서다. ## 1. printf는 형식에 맞춰 값을 해석한다 ~~~c int age = 20; double score = 91.5; printf("age=%d score=%.1f\n", age, score); ~~~ %d는 정수, %f는 실수 출력 자리다. 중요한 점은 printf가 변수 타입을 자동으로 안전하게 확인해주지 않는다는 것이다. 형식 지정자와 실제 인자의 타입이 맞지 않으면 출력이 깨지거나 정의되지 않은 동작으로 이어질 수 있다. | 지정자 | 의미 | |---|---| | %d | int | | %f | double 출력 | | %c | 문자 하나 | | %s | 문자열 | ## 2. scanf는 주소를 받는다 ~~~c int age; scanf("%d", &age); ~~~ scanf에는 age가 아니라 &age를 넘긴다. 함수가 값을 읽어서 변수에 써야 하기 때문이다. &age는 age가 저장된 주소다. 이 지점이 포인터 학습의 첫 입구다. 아직 포인터 문법을 깊게 몰라도 입력 함수는 값을 넣을 위치가 필요하다는 감각은 잡아야 한다. 문자 배열은 예외처럼 보인다. ~~~c char name[32]; scanf("%31s", name); ~~~ 배열 이름 name은 대부분의 식에서 첫 원소 주소처럼 동작한다. 그래서 &name이 아니라 name을 넘긴다. 그리고 %31s처럼 최대 길이를 제한해야 한다. %s만 쓰면 입력이 배열 크기를 넘을 수 있다. ## 3. 입력 버퍼 문제 숫자를 읽은 뒤 문자를 읽을 때 자주 문제가 생긴다. ~~~c int n; char c; scanf("%d", &n); scanf("%c", &c); ~~~ 두 번째 scanf는 사용자가 새로 입력한 문자가 아니라, 숫자 입력 뒤 남아 있던 개행 문자를 읽을 수 있다. 그래서 문자 입력 앞에는 공백을 넣는 패턴을 자주 쓴다. ~~~c scanf(" %c", &c); ~~~ 형식 문자열 앞의 공백은 공백류 문자들을 건너뛰라는 의미다. ## 4. 실전에서는 fgets를 먼저 고려한다 사용자 입력을 줄 단위로 다룰 때는 fgets가 더 안전한 출발점이다. ~~~c char line[128]; if (fgets(line, sizeof line, stdin) != NULL) { printf("input: %s", line); } ~~~ fgets는 배열 크기를 함께 받기 때문에 입력 길이를 제한할 수 있다. 숫자가 필요하면 이후 strtol 같은 변환 함수를 쓰는 방식이 더 명확하다. C 입출력은 함수 이름보다 계약을 봐야 한다. 출력은 형식 지정자와 값의 타입을 맞추고, 입력은 값을 저장할 주소와 버퍼 크기를 명확히 해야 한다. 이 두 가지를 지키면 입문 단계의 이상한 입력 버그 대부분은 피할 수 있다.
// COMMENTS
Newest First
ON THIS PAGE