C 언어에서 공백을 포함한 문자열 입력 받기: scanf
와 fgets
활용법
1. 문제 개요
C 언어의 scanf
는 문자열을 입력받을 때 기본적으로 공백을 기준으로 데이터를 구분합니다. 사용자가 이름처럼 공백이 포함된 문자열을 입력할 경우, scanf
는 첫 번째 단어까지만 읽고 이후의 데이터는 무시합니다.
이번 글에서는 scanf
로 공백을 포함한 문자열을 읽는 방법과, 이를 대체할 수 있는 fgets
의 안전하고 효율적인 사용법을 소개합니다.
2. scanf
를 활용한 공백 처리
2.1 기본 scanf
의 제한
scanf
는 %s
형식을 사용할 때 공백을 만나는 즉시 입력을 종료합니다. 따라서, "Lucas Aardvark"라는 이름을 입력하면 "Lucas"만 읽히고, 나머지는 무시됩니다.
예제:
#include <stdio.h>
int main() {
char name[256];
printf("What is your name? ");
scanf("%s", name);
printf("Hello %s. Nice to meet you.\n", name);
return 0;
}
입력:
Lucas Aardvark
출력:
Hello Lucas. Nice to meet you.
2.2 %[^\n]
형식을 사용한 개선
scanf
에서 %[^\n]
형식을 사용하면, 입력된 데이터에서 개행 문자(\n
)를 만나기 전까지 모든 문자를 읽을 수 있습니다. 이를 활용해 공백이 포함된 문자열을 읽어들일 수 있습니다.
수정된 예제:
#include <stdio.h>
int main() {
char name[256];
printf("What is your name? ");
scanf("%255[^\n]", name); // 최대 255문자까지 읽기 (버퍼 크기 - 1)
printf("Hello %s. Nice to meet you.\n", name);
return 0;
}
출력:
What is your name? Lucas Aardvark
Hello Lucas Aardvark. Nice to meet you.
주의사항:
%255[^\n]
는 입력 버퍼 오버플로우를 방지하기 위해 사용됩니다.255
는 버퍼 크기에서 널 종결 문자(\0
)를 위한 공간을 제외한 크기입니다.- 입력 데이터의 크기가 제한을 초과하면, 초과된 데이터가 입력 버퍼에 남아 이후 입력 처리에 영향을 줄 수 있습니다.
3. fgets
로 더 안전한 입력 받기
3.1 fgets
의 장점
fgets
는 입력 데이터의 크기를 제한할 수 있어, 버퍼 오버플로우를 방지하는 데 효과적입니다. 또한, 개행 문자(\n
)를 포함하여 한 줄 전체를 읽습니다.
예제:
#include <stdio.h>
#include <string.h>
int main() {
char name[256];
printf("What is your name? ");
fgets(name, sizeof(name), stdin); // 버퍼 크기를 지정하여 입력 받음
// 개행 문자 제거
name[strcspn(name, "\n")] = '\0';
printf("Hello %s. Nice to meet you.\n", name);
return 0;
}
출력:
What is your name? Lucas Aardvark
Hello Lucas Aardvark. Nice to meet you.
3.2 scanf
와 fgets
비교
항목 | scanf |
fgets |
---|---|---|
공백 포함 문자열 | 기본적으로 지원하지 않음 | 공백 포함 문자열 입력 가능 |
버퍼 오버플로우 방지 | %[^\n] 사용 시 가능 |
기본적으로 버퍼 크기 지정 가능 |
개행 문자 처리 | 수동으로 처리해야 함 | 자동으로 개행 문자를 포함하여 읽음 |
사용 편의성 | 상대적으로 복잡 | 더 간단하고 안전 |
4. 실전 코드: 사용자 입력 받기 함수화
입력을 받을 때마다 코드를 반복 작성하는 대신, 입력 처리를 위한 함수를 만들어 재사용성을 높일 수 있습니다.
예제:
#include <stdio.h>
#include <string.h>
void getInput(const char *prompt, char *buffer, size_t size) {
printf("%s", prompt);
if (fgets(buffer, size, stdin)) {
buffer[strcspn(buffer, "\n")] = '\0'; // 개행 문자 제거
}
}
int main() {
char name[256];
getInput("What is your name? ", name, sizeof(name));
printf("Hello %s. Nice to meet you.\n", name);
return 0;
}
출력:
What is your name? Lucas Aardvark
Hello Lucas Aardvark. Nice to meet you.
5. 결론
scanf
는 기본적으로 공백이 포함된 문자열 입력에 적합하지 않지만,%[^\n]
형식을 활용하면 해결할 수 있습니다.- 버퍼 오버플로우 방지와 안전성을 고려한다면,
fgets
가 더 나은 선택입니다. - 사용자 입력 처리를 함수화하여 코드의 재사용성과 가독성을 높일 수 있습니다.
C 언어에서 안전하고 효율적으로 문자열을 입력받으려면, fgets
와 같은 안전한 함수 사용을 고려하세요.