1. 실습과제4에 5번문제에서 scanf 를 사용하셨는데 scanf_s를 사용해도 되는건가요?
==> scanf_s()를 사용해서 코드 작성하셔도 됩니다.
2. 보안상 scanf_s를 사용한다고 강의 중에 말씀하셨는데 scanf, scanf_s를 써야하는 특정한 경우가 있는 것인지요?
차이점은 다음과 같습니다.
scanf_s()의 경우 문자와 문자열을 입력받을 경우에 인수값을 하나 더 입력해서 해당 크기를 넣어줘야 합니다.
scanf() 함수는 별도로 크기를 지정해 주지 않기 때문에 지정된 버퍼의 크기보다 더 많은 양의 값을 입력할 수 있기 때문에 버퍼 오버플로우에 대해서 많이 취약한 단점이 있었습니다.
(버퍼 오버플로우(Buffer Overflow) = 입력값의 크기가 버퍼 사이즈보다 커서 입력값을 버퍼에 다 담지 못할 때 문제가 되는 취약점)
따라서 scanf() 함수의 이러한 보안상 문제점을 해결하기 위해 만든 함수가 scanf_s() 입니다.
Dev C++의 경우 scanf() 함수를 사용해도 에러를 발생시키지 않지만 Visual Studio의 경우 다음과 같은 에러를 발생시키면서 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.
3. Dev C++에서 [warning] implicit declaration of function 'scanf_s' 에 대한 해결책
implicit declaration of fucntion(함수의 묵시적 선언)은 직접 만든 함수를 사용할때 그 함수를 선언하지 않았을때 발생합니다. scanf_s 함수는 Visual Studio에만 존재하는 비표준 함수이기 때문에 표준 라이브러리에 존재하지 않고, gcc기반의 다른 컴파일러나 IDC(VSC, Dev C++등)에선 작동하지 않습니다.
일단 scanf_s를 사용해서 사용자로 부터 값을 입력받는 것이 보안상 안전한 방법입니다.
그런데 아직까지 위 방법은 visual studio에만 존재하는 비표준 함수 이기 때문에
gcc 기반의 다른 컴파일러나 저희가 사용하는 Dev C++에선 실행은 되지만 warning을 발생시킵니다.
프로그래밍이라는 것이 참 복잡하고 해결해야 할 문제가 많지요?
해결책은 scanf_s=> scnaf 로 변경해야 합니다.
하지만 현업에 가서는 scanf_s를 사용해서 수행해야 하기에 저희는 현재 추세에 맞게 scanf_s를 배운 것입니다.
4. Scanf에서 & 사용
c언어를 시작하면 printf에서는 &를 안썼는데, scanf에서는 &를 쓸때도 있고, 안쓸때도있습니다.
이 부분이 많이 헷갈리실 것입니다.
변수앞에 &을 붙여 주는 이유는 해당 변수의 주소를 받기 위해서입니다.
(즉, 값을 입력하려면 변수의 주소가 필요하기 때문에 &를 사용해야 합니다.)
만약에 a라는 정수형 변수에 10이라는 값이 저장되어 있다면
출력문에서 해당 변수값을 가져와서 그대로 출력을 해 주면 됩니다.
int a=20;
printf("a의 값 = %d\n",a);
그러나 입력문에서는 값을 메모리(버퍼)에 저장하게 되는데 여기서 scanf() 함수에 포함된 '&'기호를 주소 연산자(&)라고 합니다.
즉 사용자가 입력할 값을 해당 주소에 저장하라는 신호를 보내는 것입니다.
그런데 문자열에서는 "&" 기호를 사용하지 않는데 그것은 문자열 자체에 주소를 포함하고 있기 때문입니다.
int a;
char b[20];
scanf("%d", &a); //&를 써야한다.
scanf("%s", b); //&를 안써도 된다. b 자체가 주소