본문 바로가기

프로그래밍/C언어

[C언어] scanf, scanf_s 함수

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 오랜만에 예제소스를 만들기 위해 scanf 함수를 사용하였다. 정말 간단한 소스였기때문에 에러가 날 것이라고는 생각지 않았는데......


 warning C4996: 

 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS 


경고가 두둥!



  #include <stdio.h>

 

  int main(void)

  {

  int value1, value2;

  scanf("%d %d", &value1, &value2);

  

  printf("%d + %d = %d\n", value1, value2, value1 + value2);

  printf("%d - %d = %d\n", value1, value2, value1 - value2);

 

  return 0;

  }

 


 기존에 내가 알고 있던 scanf 함수이다. 하지만 경고메세지를 살펴보면 scanf 대신 scanf_s로 사용하라고 하고 있는데 그 이유는 기존에 사용하던 scanf가 구조적으로 안정적이지 않아 여러 위험을 안고 있는 함수이기 때문이다. 그러한 문제점을 보완하여 나온 것이 scanf_s. ( 일명 _s 시리즈 ) VS2010 이상 컴파일러에서는 scanf_s 함수를 사용하도록 권장하고 있다.

 

 그렇다면 scanf_s는 어떤 점이 달라진 것일까.

 기존 scanf는 char 형이나 문자열을 넣을때 받을 수 있는 문자열의 사이즈를 넣지 않아도 사용이 가능했었다. 그로인한 문제점이 바로 오버플로우(overflow).


 기본 scanf 함수

 

 #include <stdio.h>


 int main(void)

 {

      char str[5];

      scanf("%s", str);

      printf("문자열 : %s\n", str);


      return 0;

 }



 정상적인 값을 넣을 경우

 입력값 : abc

 출력 : abc

 입력값과 출력값이 동일


 배열보다 큰 문자열을 넣을 경우

 입력값 : abcdefg

 출력 : 에러를 뿜는다.


 


 이런 경우를 예방하기 위해서 나온것이 scanf_s.


 scanf_s 함수

 #include <stdio.h>


 int main(void)

 {

      char str[5];

      scanf_s("%s", str, sizeof(str));

      printf("문자열 : %s\n", str);


      return 0;

 }


 배열보다 큰 문자열을 넣을 경우

 



 scanf_s 함수는 에러메세지를 출력하지 않고 str에 아무런 값이 들어가지 않는다. 담을 수 있는 사이즈보다 큰 값이 들어오면 아예 값을 넣지 않는것이다. _s 함수를 사용하면 이런 에러메세지를 피할 수 있다. 

 

 컴파일러에서는 _s 함수의 사용을 적극 권장하고 있지만 잘못된 값이 들어왔을때 에러메세지가 출력되는 것이 훨씬 좋을때가 많다. 위에처럼 str 값이 NULL 값으로 처리되어 버리고 에러메세지도 없다면 어디에서 코드가 잘못되었는지 찾기 쉽지 않을테니 말이다.

 

 에러메세지를 뿜어도 좋다. 난 scanf 쓸거다. 하지만 출력창에 뜨는 에러메세지는 너무 거슬린다! (사실 %c %s를 제외하면 기존 scanf와 사용방법이 같다.) 그렇다면 소스에 이렇게 추가해보자.



 #pragma warning (disable:4996)



 #include <stdio.h> 위에 선언해 주면 된다.