결론: fgets() 쓰세요.
C11이 되면서 보안상 엄청난 결함을 가지고 있던 gets() 함수가 드디어 삭제되었습니다. 이제 최신 컴파일러에서는 gets()를 사용할 수 없습니다. 사용할 수는 있어도 보안 경고가 뜰 겁니다.
비주얼 스튜디오에서는 get_s()를 사용하라고 하는군요. 그런데, gets_s()는 표준이긴 하지만 optional이라 지원되지 않는 컴파일러도 꽤 있는 것으로 알고 있습니다. 그래서 대부분은 fgets()를 더 추천하죠.
두 함수의 원형은 이렇습니다.
char *gets_s( char *str, rsize_t n ); // C11 부터, 선택사항
char *fgets( char *restrict str, int count, FILE *restrict stream ) // C99 표준
두 함수의 차이점이라면 gets_s()는 stdin에서 입력을 받고, fgets()는 입력 스트림을 직접 정해야 한다는 것 입니다.
gets_s()
n == 0 이거나 n > RSIZE_MAX일때, str == NULL일때, 혹은 입력 받은 문자열이 버퍼보다 크면 프로그램이 자동으로 터집니다 (런타임 에러)
fgets()
count < 1이면 동작이 정의되지 않습니다. count == 1일때 널 문자가 입력될 때의 동작도 정의되지 않습니다.
gets_s()는 C11 표준, fgets()는 C99 표준(이전부터 있었지만, C99에서 개정됨)입니다. 호환성 면에선 C99의 fgets()가 더 좋습니다. _s() 함수들은 선택사항이라 gets_s()를 지원하지 않는 컴파일러도 많을 겁니다.
사용법은 이렇습니다.
#include <stdio.h>
int main(void) {
char buf[100] = {""};
printf("Enter anything: ");
gets_s(buf, sizeof buf);
printf("You've entered: %s\n\n", buf);
for (int i = 0; i < 100; i++) buf[i] = '\0';
printf("Now Enter something different: ");
fgets(buf, sizeof buf, stdin);
printf("You've entered: %s\n\n", buf);
}
간단합니다. 두 번째 매개변수에 sizeof + (배열 이름) 만 작성하시면 됩니다.
fgets는 늘 하던 대로 FILE* 스트림에 stdin만 적어주면 됩니다.
저라면 막강한 C++의 string 클래스를 fgets를 쓰겠습니다. 괜히 gets_s() 썼다가 다른 환경에서 컴파일 안 되면 곤란하니까..
'C언어 > C언어 심화 & 특수' 카테고리의 다른 글
[C11] C언어 표준 스레드 실행 (0) | 2020.03.21 |
---|---|
[C99] Compound Literals, C에서의 이름없는 임시 객체 (0) | 2020.03.21 |
[C99] 포인터 최적화를 위한 restrict 키워드 (0) | 2020.03.21 |
[C11] 컴파일 타임 오류내기, static_assert (0) | 2020.03.21 |
[C99] C언어에서 표준 bool 타입 사용하기 (0) | 2020.03.21 |