아하
생활

생활꿀팁

튼실한달팽이259
튼실한달팽이259

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

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

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

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

scanf_s

55글자 더 채워주세요.
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)을 추가하면 출력 될겁니다.