개발하는 리프터 꽃게맨입니다.

[C++] scanf 가 위험한 이유, scanf 와 cin 의 차이점 본문

언어/C, C++

[C++] scanf 가 위험한 이유, scanf 와 cin 의 차이점

파워꽃게맨 2023. 12. 24. 23:31

scanf는 C 언어의 입력 함수입니다.

 

만약, 7 바이트 사이즈의 char형 string 변수에 

'Crabman' 을 입력하면 어떻게 될까요?

 

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

int main()
{
	char string[7];
	scanf("%s", string); //Crabman 을 입력하고 싶어!

	return 0;
}

 

정답은 '오류가 발생한다.'입니다.

 

보통 프로그램에서 '문자열'은 종단에 '널문자 (\0)'를 추가하여

문자열의 끝맺음을 해줍니다.

 

H e l l o \0

이런 느낌이죠.

 

그런데, 기본적으로 scanf는 입력 버퍼의 최대 크기를 모릅니다. 

그렇기에 7바이트의 버퍼에 문자열을 할당하는 순간

 

펑!

 

 

'배열의 크기보다 더 큰 데이터를 넣으려고 했다.'

라고 오류창이 뜨는 것이죠

 

7바이트의 버퍼에는 최대 6문자까지 입력할 수 있습니다.

그래서 scanf가 위험하다고 하는 것이죠.

 

그렇다면 cin이 안전한 이유는 무엇일까요?

 

#include <iostream>
using namespace std;

int main()
{
	char string[7];
	cin >> string; //Crabman 입력할 수 있겠지?

	return 0;
}

 

그러나 위 코드도 오류가 발생합니다.

결국 cin도 버퍼의 크기를 모르기 때문이죠..

 

그러나 사용자가 직접 cin에게 버퍼의 크기를 알려주면, 

cin이 직접 입력한 문자를 적절하게 잘라서 사용합니다.

 

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{
	char string[7];
	cin >> setw(7) >> string; //Crabman 진짜 입력할 수 있겠지?

	cout << string << endl;

	return 0;
}

네, 아주 잘 입력됩니다.

string은 널 문자를 포함한 7개의 문자를 가질 수 있으므로

6개의 문자까지 딱 끊고, 널문자를 추가한

C r a b m a \0 를 버퍼에 저장한 모습을 볼 수 있습니다.