c언어 scanf와 scanf_s의 차이가 뭔가요?

입력문을 작성할떄 scanf 는 출력이 될 때도있고 안될떄도 있어서

입력할때마다 scanf_s라고 써도 무방한가요?

또 scanf는 왜 안되는지 알려주시면 감사하겠습니다.

scanf_s

    16개의 답변이 있어요!

    • 안녕하세요

      scanf 함수 와  scanf_s 함수의 가장큰 차이는 scanf 의 오버플로우를 방지 하기위한 싸이즈가 있다는 겁니다.

      기존 scanf는 문자열을 넣을때 받을 수 있는 문자열 사이즈를 넣지 않아도 사용이 가능 했는데

      그로인해 오버플로우가 발생될 우려가 생겼습니다.

      때문에 scanf_s 함수에서는 사전에 예방하기 위해 나온 함수가 scanf_s 입니다.

    • 1970 년대 초에 나온 c 언어는 그당시 획기적인 언어로 선보였지만

      지금 시대에 사용하기에는 취약한 단점을 가지고 있는 함수들이 많습니다.

      scanf 는 사용자로부터 입력을 받아 변수에 대입합니다.

      이때 사용자가 변수에 담을수 있는 크기보다 더 큰 크기의 데이터를 입력한다면 오버플로우 에러를 발생하게 됩니다.

      이런 단점을 보안하고자 scanf_s 는 입력받는 데이터의 최대 크기를 지정할수 있게 합니다.

      예를 들면

      scanf("%d", &a);

      scanf_s("%d", &a, sizeof(a));

      이렇게 scanf_s 함수는 데이터의 크기를 지정하게 됩니다.

    • scanf와 scanf_s는 둘다 문자열을 받는 함수이나 scanf는 버퍼 오버플로우에 취약합니다. 할당된 버퍼에 들어갈 수 있는 양보다 더 많은 양을 넣을 수 있게 되어 그 경우에 뻗어버리죠. 하지만 scanf_s는 사이즈 인자도 같이 넣기 때문에 문자열을 입력할 수 있는 갯수를 제한해버립니다.

    • 안녕하세요

      Scanf 로 문자열을 입력받을 경우 잡아둔 메모리 영역을 벗어날 경우가 있습니다. 이러한 경우 프로그램이 손상되고 에러가 발생할 수 있습니다.

      Scanf_s는 이를 해결하기 위해 마이크로소프트에서 권장하는 사항입니다. 그런데 또 s를 사용하면 호환성에 문제가 있다고 하니 문제가 되지 않도록 길이 제한을 하거나 에러 문구를 발생시켜 알림을 주는 것도 좋은 방법이라고 생각합니다.

    • scanf 는변수를 선언하고 그 변수에 입력을 받는 방식인데요.

      scanf("입력받을 형태", &변수이름); 을 써주시면 입력받을수 있습니다.

      scanf_s는

      scanf랑 별차이가 없습니다. 다만 다른점은 뒤에 입력받을 크기를 입력하는것

      scanf_s("입력받을 형태",&변수이름,입력받을크기); 을 써 주시면 입력받을수 있습니다

      왜 scanf_s를 써야하는가?

      오버플로우 공격을 방지하기 위해서 그렇습니다.

      참고

      https://docs.microsoft.com/ko-kr/previous-versions/visualstudio/visual-studio-2012/w40768et(v=vs.110)?redirectedfrom=MSDN

    • 네 scanf_s로만 써도 무방합니다.

      다만 컴파일러가 옛날버전이라면 scanf_s자체가 안먹을수도 있으니 참고 바랍니다.

      scanf와 scanfs의 차이를 보시고 원하시는 걸 사용하시면 됩니다.

      전 현업에서 scanf_s보단 scanf를 더 많이 쓰는 편 입니다.

      <scanf 예시>

      char my_str[10];

      scanf("%s", my_str);

      printf("내문자 : %s\n",my_str);

      여기서 만약 abcdefghijklmnopqrsf 를 입력한다고 하면 overflow가 나는데요.

      이때 scanf는 오류를 뱃어냅니다.

      scanf_s는 그냥 빈문자열을 뱃어냅니다.

    • 기존에 사용하던 scanf함수는 지정된 버퍼의 크기보다 더 많은 양의 문자를 넣을수 있기 때문에 버퍼오버플로우에 대해서 많이 취약했다.

      이러한 부분을 보완하고자 만든 함수가 scanfs이다. 즉, 보안을 위해서 보완한 함수이다.


      scanf와 scanf_s의 사용법은 거의 똑같지만, 문자와, 문자열을 입력받을 경우에 인자값으로 하나를 더 입력해 줘야한다.


      #include<stdio.h> int main() { char arr[20]; scanf("%s",arr); }


      - scanf 함수는 arr 크기가 20일때 arr에 20이상의 문자를 넣을수 있다는 취약점(버퍼오버플로우)이 있었다.


      #include<stdio.h> int main() { char arr[20]; scanf_s("%s",arr,sizeof(arr)); }


      - scanf_s 함수는 문자열의 크기를 인자값으로 넘겨주어 arr 크기가 20일때 arr에 19개의 문자열을 입력할 수 있게 되었다. (1개는 \0을 넣을 공간)

      - 그리고 버퍼의 크기를 주지 않으면, 출력이 되지 않는다.


      #include<stdio.h> int main() { char arr[20]; char str[20]; scanf_s("%s %s",arr,sizeof(arr),str,sizeof(str)); }


      - 만약 문자열을 두개 이상 입력 받고싶으면 위의 코드처럼 배열1 이름, 배열1 크기, 배열2 이름, 배열2 크기 순으로 넣어주면 된다.

    • scanf 함수는 형식에 맞춰서 값을 입력받고 이를 할당된 메모리 주소에 값을 넣게 되는데요,

      값을 넣을때 할당된 메모리 크기를 벗어날 위험이 있습니다.

      이러한 문제를 개선하기 위해 scanf_s 함수가 나왔고, 비주얼스튜디오 2005 이상부터는 scanf를 에러로 지정해두었죠

      코드의 제일 위에 #define _CRT_SECURE_NO_WARNINGS 를 작성하게되면 scanf를 사용해도 에러가 발생하지않고 사용할 수 있습니다.

    • 안녕하세요

      scanf 가 버퍼오버플로우에 취약한 문제가 있기 때문에 생긴것이 scanf_s 입니다

      버퍼오버플로우란 할당된 버퍼에 들어갈 수 있는 양보다 많이 넣게 되면 생기는 오류인데, scanf_s 를 쓸 때 3번째 인수로 버퍼메모리 크기를 지정해서 발생될 오버플로우를 미리 방지하는 형식 입니다.

    • scanf와 scanf_s 사용법을 보면 아래와 같은 차이가 있습니다.

      scanf("입력받을 형태",&변수이름); 

      scanf_s("입력받을 형태",&변수이름,입력받을크기); 

      차이점을 보시면 입력받을 크기를 입력하냐 아니냐의 차이입니다. _s는 size를 의미하고 그 이상의 크기를 입력받지 못하게 합니다.

      도움이 되셨길 바랍니다.

    • scanf_s 함수를 사용하세요

      C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

      "scanf 함수는 위험하니 scanf_s를 사용을 권장하며 무시하고 사용하려면 _CRT_SECURE_NO_WARNINGS 를 사용해라"

      scanf 함수는 형식지정자에 맞춰서 값을 입력받고 이를 할당된 메모리 주소에 값을 넣는데, 이 입력 인자로 받은 주소에 값을 저장하는 과정에서 할당된 메모리의 크기를 벗어날 위험이있다. 이 문제점이 바로 "버퍼 오버플로우"

      scanf 함수의 버퍼 오버플로우 문제를 개선하기위해 새롭게 scanf_s함수가 등장하게 되었고 MS사에서는 비주얼 스튜디오 2005 이상 버전부터 scanf를 에러로 지정해두었고 scanf_s를 표준으로 지정하였다.

    • 일단 기능상은 동일합니다.
      둘다 표준 입력 스트림 stdin 에서 데이터를 읽어 인자로 받은 곳에 쓰는 기능입니다.


      다만 차이점은 뒤의 버전은 secure 기능이 포함되어 있는 scanf 버전이라고 보시면 됩니다.
      _s 버전의 CRT(C Runtime 함수)는 일반적으로 버퍼에 대한 크기를 제공받습니다.

      char s[10]; scanf_s("%9s", s, (unsigned)_countof(s)); // 버퍼의 크기는 10, 길이는 9개로 지정이 되었습니다.

      이 입력받은 정보를 바탕으로 토큰이 너무 커서 버퍼에 담기에 초과하는 경우가 있을 수 있습니다.
      위의 코드의 경우 입력값이 9개를 초과하는 경우 발생할 수 있습니다.
      (문자열의 경우 제일 끝이 terminal null 이 포함되기에 10이 아닌 9가 됩니다.)

      따라서 버퍼 오버플로(혹은 버퍼 오버런)이라는 취약점을 대비 할 수 있게 됩니다.

      더 자세한 내용은 아래 MSDN의 문서를 참고하세요.

    • 둘의 기능상의 차이는 없습니다.

      scanf 가 전달 받은 값의 메모리를 벗어나게 되면 버퍼오버플로우 에러가 발생하게 됩니다.

      scanf_s 를 사용하여 오버플로우를 방지합니다.

      비주얼스튜디오2005버전 이상부터는 scanf를 에러로 지정하여 scanf_s를 사용하도록 하고있습니다.


    •  scanf와 scanf_s 둘다 기능상의 차이는 없습니다.

      표준 입력스트림에서 정해진 포맷으로 데이트를 입력받는 함수입니다.

      다만 scanf_s의 경우 추가 파라미터가 존재합니다.

      오버플로우 방지를 위해 문자열을 읽을때 최대 몇개까지 문자 읽을지를 지정하게됩니다.

      * 오버플로우 : 프로세스 메모리 영역중 버퍼에 초과하는 값을 읽거나 쓰게되어 원하지 않는 값을 읽거나 쓰게되는 현상으로 해킹공격시 이러한 취약점을 이용하여 프로그램을 해킹하기도 합니다.

    • scanf함수는 버퍼사이즈를 인자로 받지 않습니다. 그리하여 입력받은 사이즈가 만약 인자로 들어가는 버퍼 사이즈보다 커질 시에 메모리 침범 문제가 있을수 있습니다.

      이에 비해 scanf_s는 사이즈를 인자로받아 이러한 문제를 보완할수있는 함수라고 생각하시면 될 것 같습니다. 한번 각각 짜보시면 이해하시기수월하실거예요.

    • 안녕하세요

      scanf같은 경우 버퍼오버플로우에 취약해서 scanf_s를 사용하도록 권장합니다.

      scanf_s는 문자열을 쓸때 버퍼 메모리의 크기를 3번째 인자로 미리 설정하여서 버퍼 오버플로우를 방지합니다.

      기존의 scanf로 출력하고 싶을때는 소스파일을 만드실때 security를 해제하시거나

      소스코드 첫부분에 #pragma warning(disable:4996)을 추가하면 출력 될겁니다.