개발하는 리프터 꽃게맨입니다.
[C++] scanf 가 위험한 이유, scanf 와 cin 의 차이점 본문
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 를 버퍼에 저장한 모습을 볼 수 있습니다.
'언어 > C, C++' 카테고리의 다른 글
[C++] 연산자 오버로딩 (0) | 2024.01.06 |
---|---|
[C++] C++에서 구조체 vs 클래스, 차이가 뭘까? (0) | 2023.12.28 |
[C++] 클래스 생성자 (feat. 복사 생성자, 얕은 복사 & 깊은 복사) (2) | 2023.12.27 |
[C++] malloc vs new (2) | 2023.12.27 |
[C++] 조정자 (Manipulator) (0) | 2023.12.24 |