c++ 프로그래밍, 입력(input) scnaf, cin 메모리 안전하게 쓰기

[공부/C++] - C++ 프로그래밍, 네임스페이스 namespace란?

 

C++ 프로그래밍, 네임스페이스 namespace란?

네임스페이스(namespace) 말 그대로 공간의 이름이다. 어떤 공간을 정의하는데 거기에 이름을 정해준다고 생각하자. 네임스페이스가 다르다는 것은 서로 다른 공간에서 존재한다는 것이다. 이름이 다른 공간이니..

minmong.tistory.com

안녕하세요 민몽입니다 :)

오늘은 C++ 프로그래밍 입력(input)에 대해서 공부합시다.

키보드로 받은 입력을 해보자

C 스타일 입력 scnaf

char firstEnglish[20];
scanf("%s", firstEnglish);

 

키보드로부터 스트링을 읽어서 firstEnglish에 넣어준다.

이렇게 사용할 경우 안전하지 않다.

C++ 스타일 입력 cin

char firstEnglish[20];
cin >> firstEnglish;

cout console out : 콘솔창으로 내보내죠.

cin  console in : 콘솔창에 있는 걸 가져와죠. 

 

이렇게 생각하자.

 

cout을 사용할 때에는 '<<'을 사용했었는데 입력을 할 때에는 '>>'을 사용한다. 

extraction 익스트랙션 추출 연산자 이다.

뽑아오는 연산자라고 생각하자.

 

정수형 읽기

float price;
cin >> price;
cout << "I have to go at " << hours <<endl

따로 포맷을 지정해 주지 않더라도 알아서 int로 읽어 올 수 있다. '%d'를 사용하지 않아도 된다.

 

실수 또한 마찬가지이다.

float price;
cin >> price;
cout << "The price of coffee is $" << price << "." <<endl

scanf()는 왜 위험할 까?

char 배열에 "ABCD"를 넣어보자.

char firstEnglish[4];
scanf("%s", firstEnglish);

char 배열 firstEnglish에 "ABCD"를 입력하려고 한다.

어떻게 될 까?

"ABCD" 네 글자 배열 4개를 잡아 놨네 잘 되겠네?

firshEnglish자체는 배열이지만 char 포인터이다. 

따라서, 실제로 어느 정도 메모리가 할당되어 있는지 입력을 할 때에 알 수 없다.

그래서 스트링이 끝났다는 것을 인지 할 수 있도록 마지막 특수한 char인 null charf를 넣어주게 된다.

실제로 위의 코드를 읽게 되면 "ABCD" 아직은 괜찮다 4개 할당 문자 4개...

 

하지만 "ABCD"를 넣고 null char를 넣게 되면 우리가 미리 할당하지 않은 메모리에 접근하게 된다.
우리가 소유하고 있지 않은 메모리를 덮어쓰려고 하게 되니 문제가 발생하게 된다.

이렇게 배열을 늘려주면 해결은 되지만 문자열이 또 늘어가게 되면 같은 문제가 발생한다.

입력값에 따라서 또다시 버퍼가 충분하지 않을 수 있다.

char firstEnglish[5];
scanf("%s", firstEnglish);

배열이 5개로 될 경우 정상 이지만 이거도 문제가 된다.

scanf()는 경계 검사를 하지 않는다!

cin은 어떠할까?

char firstEnglish[4];
cin >> firstEnglish;

scanf와 차이가 있을까?

firstEnglish는 여전히 char 포인터이다. 마찬가지로 얼마나 메모리가 할당되어있는지 알 수 없다.

C에서의 수정

char line[512];
char temp[512];
char firstEnglish[4];

// 511 char + null char
if(fgets(line, 512, stdin) != NULL) //line에 담을수 있는 만큼의 char를 읽어오자
{
	//같은 메모리 크기의 temp로 읽어 온다. 길이를 4글자 미만일때만 copy 해주자.
	if(sscanf(line, "%s", temp) == 1 && strLen(temp) < 4)
	{
		strcpy(firstEnglish, temp);
	}
}

fgets와 sscanf를 이용하고 string 길이를 검사한 후 우리가 원하는 firstEnglish에 copy를 해준다.

C++에서의 수정

char firstEnglish[4];
cin >> setw(4) >> firstEnglish 

manipulator를 이용하면 쉽게 할 수 있다. manipulator는 입력, 출력을 조작할 수 있는 함수라고 생각하자.

 

setw()는 manipulator의 한 종류이다.

cin에서 읽어 올 때에 버퍼 사이즈를 4로 해줘 라고 하는 것과 같다.

이렇게 setw(4)를 추가하게 되면 알아서 "ABCD"를 입력하더라도 "ABC"까지 읽어오고 null char를 붙여준다.

 

오늘은 C++ 프로그래밍 입력(input), scanf, cin에 대해서 공부했습니다. 

 

그리드형(광고전용)

이 글을 공유합시다

facebook twitter googleplus kakaoTalk kakaostory naver band

댓글

Designed by JB FACTORY