▷ gets / puts
gets : 사용자로부터 문자열을 입력받아
함수의 인자로 명시한 주소의 메모리에 저장한다.
getchar함수와 같은 점은 입출력버퍼가 비어있는지 확인하고
비어있다면 문자 혹은 문자열을 입력받아 입출력버퍼에 저장한다는 점이고,
다른 점은 문자 하나씩 반환하는 것이 아니라 문자열을 한꺼번에 반환한다.
puts : 문자열을 모니터 화면(콘솔)에 출력하는 함수.
puts함수는 출력할 문자열의 길이를 따로 명시하지 않아도
알아서 출력하는데 C언어에서 모든 문자열은 null(0)로 끝나기 때문에
'0'이 나올때까지 출력하는 것이다.
char Name[5];
gets(Name);
puts(Name);
이 코드는 char형의 자료형 5개를 확보하라는 배열 선언이다.
이 선언에서 Name는 배열을 대표하는 이름이며
그 실체는 연속된 메모리 시작의 주소이며 식별자라고 부른다.
char형인 자료형이 5개 확보되었으므로 5바이트의 메모리가 확보되며,
gets함수는 버퍼에 메모리가 비었는지 확인하고 비었으면 사용자의 입력을 기다린다.
‘TEST’라고 입력하면 Name라는 식별자의 메모리 시작의 주소부터
차례대로 문자가 저장되고 반환하게 된다.
그리고 puts함수는 gets함수가 반환한 문자열인 ‘TEST’를 콘솔화면에 출력하게 된다.
* 참고 *
비주얼스튜디오(VS)에서는 gets함수는 (C언어 자체에서 가지고 있는 결함)
보안에 결함이 있으므로 gets_s를 사용하는 것을 권하고 있다.
char Name[4];
gets_s(Name, sizeof(Name));
2번째 매개변수에 sizeof연산자를 적어준다
sizeof연산자는 지정한 대상의 메모리 주소를 표시한다.
소스 실행결과 Name이라는 식별자가 가진 자료형이 몇 바이트인지 계산한다.
char형의 자료형은 1바이트인데 4개의 배열을 가지고 있으므로 총 4바이트이다.
그러므로 gets_s(Name, 4); 라고도 작성할 수 있다.
하지만 왠만하면 sizeof라는 연산자를 사용하도록 하는 것을 권장.
* 버퍼오버플로우(Buffer overflow)에 의한 버퍼오버런(Buffer overrun)
위 코드로 예를 들면 자료형이 char형인 식별자 Name은
4바이트의 메모리 공간을 확보했는데 만약에 4글자 이상을 입력하게 되면?
4글자 이상을 입력하고 엔터를 누르면 VS에서 실행 오류가 발생한다.
배열 관련 설명에서 기술했듯이
C언어에서는 문자열의 마지막은 항상 null(0)로 끝나는데
4바이트의 메모리 공간은 3개의 문자와 null문자로 끝나기 때문에
확보한 4바이트 메모리 공간의 저장 허용범위를 초과하게 되는 것이다.
하지만 이 gets함수는 배열선언으로 확보한 메모리의 크기만큼만 제한해서
사용자에게 문자열을 입력받는 것이 아니라
사용자가 문자열을 입력하는 대로 그대로를 제한 없이 받기 때문에
이러한 오류가 발생한다.
그래서 C언어에서는 메모리 관리를 본인이 해야하고
그만큼 코드 작성시 이에 관해서 보다 깊이 생각해봐야겠다.
** 잘못알고 있는 것이 있으면 댓글로 알려주시면 감사하겠습니다! **
'프로그래밍 > C언어' 카테고리의 다른 글
형식 문자열 입출력 함수 ( scanf ) (2) (0) | 2018.06.05 |
---|---|
형식 문자열 입출력 함수 ( printf ) (1) (0) | 2018.06.04 |
문자열 입출력 함수 (배열) (1) (0) | 2018.06.01 |
문자 입출력 함수 (_getch / _getche) (2) (0) | 2018.06.01 |
문자 입출력 함수 (getchar / putchar) (1) (0) | 2018.05.31 |