3.3scanf()함수의 기본적인 사용법
그동안 앞에서 console 화면에 문자를 출력하는 printf 함수에 어느 정도 익숙해졌을 것이다.이번에는 반대로 console 창에서 사용자의 입력을 받아오는 scanf 함수의 기본적인 사용법에 대해 알아보자.
먼저 코드를 보면서 어떻게 하는지 설명하고 scanf와 관련된 새로운 개념을 하나 설명한다.
우선 코드부터 보자. 원래 C표준에서 scanf를 사용하는 것은 어려운 일이 아니다.입력받는 방법을 알아보기 위해 scanf를 사용해보자.위에 선언된 변수 i를 입력받기로 하자. scanf의 사용법은 printf의 사용법과 거의 대응하고 있다.그러나 (콤마) 뒷글자 앞에 ampersand 또는 and라고 부른다 & 를 붙인다.정확한 명칭은 ampersand이다.
하지만 코드를 build하면 오류가 난다.이 에러는 microsoft에서만 발생한다.이 오류를 없애고 scanf를 사용하는 방법 2가지를 알려줄게.
첫 번째 방법은 간단한 방법으로 오류 메시지에 있는 ‘_CRT_SECURE_NO_WARNINGS’를 복사하여 맨 위에 #define과 함께 붙어 두었다가 다시 빌드를 하면 문제없이 작동한다.define 부분을 macro(매크로)라고 한다. <후술>
이 방법은 gcc와 호환되지 않는 문제가 있다.
두 번째 방법은 우리가 사용하는 프로젝트에서 우클릭해서 Properties에 들어가서 지금 Debuger를 사용하기 위해서 Debug 모드로 공부하고 있기 때문에 C/C+-> Preprocessor-> Configuration 설정을 Active(Debug)에 둔다.
Active(Debug) -> PreprocessorDefinition 부분에서 기존 문자열 맨 뒤에; (세미콜론)을 입력한 후, 그 후에 _CRT_SECURE_NO_WARNING을 붙인다.
또는 edit을 눌러
_Debug 앞에 enter를 눌러 빈칸을 만들고 거기에 _CRT_SECURE_NO_WARNINGS를 붙여놓는 방법도 있다.
Apply ->OK를 선택한다.
그리고 빌드를 다시 시작하면 오류없이 실행된다.
이 방법에서 주의해야 할 점은 지금은 Debug 모드로 하고 있지만 나중에 공부할 때는 특히 자료 구조, 알고리즘을 공부할 때는 release 모드로 해서 코딩하게 된다.그때는 옵션이 바뀌지만 PreprocessorDefinitions 전처리기의 정의에도 _CRT_SECURE_NO_WARNINGS를 넣어야 한다.
이는 C뿐만 아니라 C+도 계속 사용한다면 익숙해져야 할 점이다.
두 번째 방법을 권장한다.이유는 전처리를 사용할 필요 없이 코드를 깔끔하게 작성할 수 있기 때문이다.
Ctrl+F5로 실행시키면 한참 기다리고 있다.
예를 들어 숫자 7을 넣고 enter를 치면 i 값이 0으로 초기화 되고 scanf 함수로 입력한 값 7을 스캔해서 가져오고 변수 i에 7을 넣는 것입니다.
scanf에서 f는 printf에서 f와 동일한 f(formatted)이다.printf도 출력을 어떻게 하는지 즉”Valueis%d
“를 formatting 하고 있고, scanf에서는 입력을 어떻게 받아야 하는지, 즉 “%d”를 formatting 하고 있다.<상세한 옵션은 다른 자료형 공부이면서 후술>
우선 콘솔 창에서 사용자의 입력을 받아들일 때 C언어에서는 scanf가 이렇게 작동하는 것으로 알아두자.참고로 C+나 다른 언어로 가면 약간 다른 방법을 쓰지만 기본적인 원리는 거의 비슷하게 작동한다.
visual studiocode에서는 GCC 컴파일러를 사용하면 #define_CRT_SECURE_NO_WARNINGS 없이 그냥 scanf를 사용해도 된다.
이렇게 실행시키면 문제없이 작동한다.+) 기타방법 참고 http://blog.naver.com/dnwn306/221905756951errorC4996:’scanf’:Thisfunctionorvariablemaybeunsafe.Considerusingscanf_si…blog.naver.com#define_CRT_SECURE_NO_WARNINGS는 Visual Studio, microsoft로만 붙인다. 그 이유에 대해 지금부터 설명해 본다.
scanf에 &가 붙는다는 것은 매우 중요하다.실수를 많이 하기 때문이다.
우리가 프로그램을 실행하면 위에서 내려온다.i에 0이 들어가서 내려가면서 scanf를 만난다. scanf를 호출할때 scanf함수의 입력으로 ( )안에 물건을 넣으면서 무언가를 기능으로 수행해달라고 말한다.
이때 변수 이름 앞에 & 를 붙이면 변수 자체를 건네주는 것이 아니라 변수의 주소를 전달한다.실제로 c언어에는 변수 자체를 넘기는 기능은 없다.& 를 변수명 앞에 붙여서 scanf함수에 넣으면 수신측으로부터 주소(10)를 받는다.그러므로 scanf함수로 사용자가 콘솔 창에 무언가를 입력하면 해당 주소에 해당하는 메모리의 값(7)을 덮어쓴다.즉 입력을 받는 것이다.
그런데 마이크로소프트에서 visual studio용 C/C+ 컴파일러를 만들 때 scanf에 걱정이 되는 측면이 하나 있었다.특정한 경우에는 scanf가 사용자로부터 입력받은 것을 해당 주소의 메모리에만 넣어야 하는데 이후 주소의 메모리까지 덮어쓰면서 보안 위험이 생긴 것이다.해킹을 할 때 사용할 위험이 있다고 판단하고 대신 scanf_s라는 함수를 사용하길 바란다.이것은 microsoft의 입장이며, 나중에 Windows용 소프트웨어를 개발할 때는 그것을 사용해도 좋다.
우선 컴퓨터의 원리를 이해한다는 측면에서도 이런 개념이 존재한다는 것을 아는 것이 도움이 된다.
&는 그 뒤에 있는 변수에 주소를 알고 싶을 때 사용한다.그래서 scanf 함수에 변수의 주소를 알려준다.그러면 scanf 함수가 주소를 통해 메모리에 직접 접근할 수 있다.
scanf 함수는 자신의 본체( )에서 변수 i에 직접 접근할 수 없다.그럼에도 불구하고 scanf는 입력을 받는 것이므로 i라는 변수에 접근하여 입력된 값을 넣어야 한다.또한, 복수의 입력을 받을 수 있다.<나중에 예제 설명하면서 후술> 그러한 이유 때문에 scanf에게 주소를 주고 콘솔 창에 입력을 하면 scanf 함수가 그 주소를 이용하여 주소에 해당하는 메모리에 있는 값을 직접 바꾼다.
그러면 scanf 함수가 종료된 후에 빨간 점 정도 왔을 때 scanf가 i의 값을 바꿨기 때문에 이미 i의 값은 바뀌었다.즉 scanf함수로 주소를 넘겨받아 주소의 메모리를 직접 덮어쓰기했기 때문에 scanf함수가 끝났을 때 i값이 이미 달라졌다는 것이다.그리고 printf를 통해 i를 출력하면 바뀐 값인 7이 나온다는 것이다.
왜 이렇게 하지?왜냐하면 c문법에서는 함수의 출력이 하나밖에 없다.scanf 함수는 여러 변수를 입력받아 그 값을 바꿔야 하는데 그것을 출력할 수 없기 때문이다.
출처 http://www.inflearn.com/course/following-c/dashboard’ 타베상+’의 성원에 힘입어 새롭게 개발된 C언어로 시작하는 프로그래밍 입문 강의입니다. ‘타베 씨’와 함께 프로그래밍 인생을 업그레이드해 보세요. 입문 초급 프로그래밍 언어 C온라인 강의 C언어 종언어 C강의 타베상 홍정모 프로그래밍 www.inflearn.com