[C++] 문자열 입력 getline()과 버퍼오버플로우

2019. 7. 27. 20:55 기타/C++

[C++] 문자열 입력 getline()과 버퍼오버플로우 


문자열을 입력받을 때, cin >>  을 보통 사용한다.


하지만 cin 으로 문자열을 입력받을 때 문제점들이 있다.


(1) 버퍼 오버플로우


cin으로 입력받는 배열의 크기를 넘어서는 문자열을 cin 을 통해 입력받으면, 배열의 크기를 넘어  다른 변수 소유의 메모리에 덮어쓰게 된다.

이것은 의도하지 않은 변경을 발생시키며, 심각한 문제를 일으킬 수 있다.

이것을 버퍼 오버 플로우 라고 한다.


(2) cin을 사용한 연속된 문자열 입력시 공백 처리


cin 을 연속으로 사용하여 2번의 문자열을 받을 때 공백을 만나면 다음 cin의 변수로 데이터가 넘어간다.

예를들어, I'm Hyeon 을 입력하면,  I'm 은 첫번째 변수에 Hyeon은 두번째 변수에 들어간다.

공백처리를 하지 못하게 된다.


이러한 문제를 해결하기 위하여, 문자열을 입력받을 때 getline() 함수를 사용한다.



(1) 배열에 문자열 입력


char cs[20];

cin.getline(cs, 20);


위와 같이 사용하면 입력받은 문자열이 cs 배열에 대입된다.

여기서 20개 이상의 문자열을 입력받으면, 20까지만 입력받게된다.

공백또한 포함하여 입력받는다.


(2) string에 문자열 입력


string cpps;

getline(cin, cpps);


cin 명령어로 받은 문자열을 cpps string 변수에 담는다.

문자열 크기의 제한은 없다.

공백또한 포함하여 입력받는다.


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



int main(){

    char cs[20];
    string cpps;

    cin.getline(cs, 20);
    cin.clear();

    getline(cin, cpps);

    cout << "cs = " << cs << endl;
    cout << "cpps = " << cpps << endl;

    return 0;
}


소스코드를 보면 cin.clear()가 있다.

이것은 첫번째 cin 에서 실패했을때, 버퍼를 지우고 진행할 수 있도록 한다.


첫번째 cin 에서 20자가 넘는 문자열을 입력받으면, 20자리까지만 cs 에 입력되고 결과는 fail 이 된다.

fail이 되어 다음 cin을 입력받지 않는다.


따라서, 첫번째 cin에서 fail이 발생해도 cin.clear()를 통해 fail 버퍼를 제거하면 다음 cin에서 문자열을 받을 수 있게 된다.



출처: https://hyeonstorage.tistory.com/306?category=601868 [개발이 하고 싶어요]