[C] Q: scanf에서 오류가 나요. in Visual Studio

언어/C 2018. 12. 30. 21:05

일단 이건 비주얼 스튜디오에서만 해당되는 문제입니다.


입력을 받는 간단한 프로그램을 하나 짜보도록 하죠.


1
2
3
4
5
6
7
8
9
10
11
12
#include "stdafx.h"
 
#include <iostream>
 
int main()
{
    char buffer[100];
 
    printf("암거나 입력하세요 : ");
    scanf("%s", buffer);
    printf("결과 %s", buffer);
}
cs



VS에서는 이렇게 문법적으로 아무런 문제도 없는 코드를 짜도, 문제가 발생할 수 있습니다.

초심자들이 한번씩은 걸려드는 함정이죠.


자 오류가 떴습니다. 근데 대체 뭐라고 하는걸까요?

scanf 함수는 안전하지 않으니까 scanf_s를 쓰라고 하는 겁니다.


근데 그건 니들 생각이고, 나는 그걸 쓰고싶지 않아요. 




1.define(안됐는데 알고보니 됨)

어쨌든 scanf를 쓰고싶으면 _CRT_SECURE_NO_WARNINGS라는 매크로를 정의하라고 하는데요. 그럼 이렇게 짜면 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
#include "stdafx.h"
 
#include <iostream>
#define _CRT_SECURE_NO_WARNINGS //잔소리좀 하지 말
 
int main()
{
    char buffer[100];
 
    printf("암거나 입력하세요 : ");
    scanf("%s", buffer);
    printf("결과 %s", buffer);
}
cs

컴파일을 해볼까요?



이런 빌어먹을. 그래도 안된다고 합니다. 얘들이 왜이러지? 예전에는 이러면 됐었는데 뭔가 바뀌었나봅니다.


수정) 알고보니 define을 맨 위에 둬야한다네요. 잘못 씀.



2.pragma

다른 매크로를 써보죠, pragma란 것도 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "stdafx.h"
 
#include <iostream>
 
#pragma warning(disable:4996//좀 닥쳐봐
 
int main()
{
    char buffer[100];
 
    printf("암거나 입력하세요 : ");
    scanf("%s", buffer);
    printf("결과 %s", buffer);
}
cs

다시 컴파일


오! 이번에는 다행히 됩니다.



3.그냥 scanf_s를 쓸까?

근데 저놈들은 이게ㅔ 뭐라고 자꾸 쓰라고 강요를 하는 걸까요?

실제로 scanf에 취약점이 존재하기 때문입니다. 전달받은 변수보다 입력으로 들어오는 값이 더 크면 버퍼오버플로가 발생하는데, 이게 상당히 위험할 수 있거든요.

그래서 더 큰 값이 들어와도 잘라버릴 수 있도록 맨 마지막 인자로 변수의 크기를 넣어줍니다. '너무 커도 이 변수 크기까지만 넣어라!' 라는 뜻이죠. 


이렇게요.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include "stdafx.h"
 
#include <iostream>
 
int main()
{
    char buffer[100];
 
    printf("암거나 입력하세요 : ");
    scanf_s("%s", buffer, sizeof(buffer)); //이제 됐냐?
    printf("결과 %s", buffer);
}
 
cs


잘 됩니다.


근데 사실 _s는 그렇게 좋은 기능만은 아닙니다. 이걸 이렇게 강력하게 지원하는 컴파일러가 사실상 이거밖에 없는데요... 

굳이 이걸 쓰지 않아도 취약점을 막을 수 있는 방법이 많기 때문입니다.. 마지막 인자 때문에 추가되는 오버헤드도 있고요.




4.프로젝트 설정

코드에 손을 대고 싶지 않다면, 좀더 근본적으로 문제를 차단할 수도 있습니다.

자꾸 _s 버전 쓰라고 강요하는걸 SDL 체크라고 하는데요. 이걸 꺼버리면 됩니다.


솔루션 탐색기 창에서 프로젝트 파일에 마우스 오른쪽 버튼을 누르고

속성 창으로 들어갑니다.


그리고 C/C++ -> 일반 -> SDL 검사에서 '아니요'를 선택해주시고 확인 누르시면


잘 됩니다.

설정

트랙백

댓글