C 이론

[C] 표준 입력 함수 scanf, getchar, gets, getch, getche, fgets)

ruming 2021. 5. 23. 06:49

평소 fgets나 gets함수는 잘 안쓰는 편인데, 입력 받을 때 scanf만 쓰는 것으로는 한계가 있기 떄문에 각 함수의 특징을 알아둘 필요가 있을 것 같다. 

 

1-1. scanf()

1-2. sscanf()

2. getchar()

3-1. gets()

3-2. get_s()

3-3. fgets()

4. getche()

4-2. getch()

 


 

1-1. scanf()

stdio.h

 

- 공백을 읽을 수가 없어 문자열을 입력받을 때는 적합하지 않다. 

예) hello world를 %s로 입력받을 경우 hello만 입력이 된다. (enter값을 data로 취급하지 않음)

 

- 입력 data를 구별해주기 위해 공백문자를 구분 문자로 취급한다.

- 버퍼에서 data를 읽어 들인 후에 버퍼 포인터를 엔터 값 뒤로 이동시켜 주지 않는다.

 

자리수를 지정하거나 여러가지 format으로 입력받을 때 쓰는 것 같다.

예) %02d, %d:%d

 

1-2. sscanf()

입력을 키보드가 아닌 char * 에서 받아온다.

사용자 입력이 있는 프로그램을 테스트할 때 계속해서 같은 입력을 주어야하는 경우 유용하다.

char a, b[200];
int c, i;
i = sscanf("A abc 1", "%c %s %d", &a, b, &c);
printf("%d %c %s %d\n", i, a, b, c);

3 A abc 1

리턴값이 정상적으로 입력이 진행된 포맷의 개수다.

 

입력값에 오류가 있을 경우

#include <stdio.h>
int main(){
	char a, b[200];
	int c, i;
	i = sscanf("AB abc 123", "%c %s %d", &a, b, &c);
	printf("%d %c %s %d\n", i, a, b, c);
    return 0;
}

2 A B 0

scanf처럼 입력 오류를 제대로 걸러내지 못한다.

 

자세한 설명 -> https://modoocode.com/67

 

 

2. getchar()

stdio.h

 

문자 전용 입력 함수, 문자 한개만 읽어들인다. 

 → 키보드 버퍼로부터 입력을 받는다.

키보드 버퍼가 비어있으면 사용자의 키보드 입력을 기다린다. 1개의 문자를 입력한다고 함수가 종료되는 것은 아니고, Enter 입력이 있을때까지 키보드 입력을 받는다.

키보드 버퍼에 존재하는 data중에서 버퍼 포인터가 위치한 곳으로부터 1byte분량을 꺼내오고 버퍼 포인터를 1byte만큼 이동시킨다.

 

참고 블로그에서 이런 예제를 발견했다.

#include <stdio.h>
int main(){
	char ch;
	ch = getchar();
	putchar(ch);
	ch = getchar();
	putchar(ch);
    return 0;
}

여기서 abcd[enter]를 입력하면 ab가 출력된다.

키보드 버퍼에 a, b, c, d, enter까지 5개의 문자가 저장된다고 한다. getchar()에서 a를 가져오고, 두번째 getchar에서 b를 가져온다. 키보드 버퍼에 이미 5개의 문자가 저장되어 있기 때문에 또 입력을 받지 않는다. 키보드 버퍼로 입력받는다는 게 이런 뜻인가보다.

그리고 이 점은 주의해야 할 것 같다. 키보드 버퍼에 c, d, enter가 남아 있기 때문에 뒤에 scanf나 gets가 오면 입력으로 받아들여지기 때문이다. (필자의 경우 scanf에 enter가 들어가는 것을 방지하기 위해 getchar()로 엔터를 받은 경험이 있다. 포스팅을 쓰게 된 원인...)

 

그리고 a[enter]로 입력할 경우에, enter를 입력으로 받아들이기 때문에 a[enter]로 출력이 된다. 만약 getchar를 연속으로 쓴다면 enter로 구분할 수는 없을 것 같다.

 

*참고

fflush(); -> 키보드 버퍼를 모두 비워주는 함수다.

 

3-1. gets()

stdio.h

 

문자열 전용 입력함수

키보드 버퍼에 enter값이 있을 경우, enter 값을 문자열 data로 취급하여 null값으로 변환하여 문자 끝에 저장하고 키보드 버퍼 포인터를 enter값 뒤로 이동시킨다.

 

문자열 변수의 길이보다 긴 글자들을 입력하면 시스템에 문제가 발생할 수 있다.

char형 크기가 정해진 배열만 사용 가능하다.

 

주어진 저장공간보다 긴 문자열의 입력에 대한 아무런 대책이 없기 때문에 위험하다. 대체함수로 gets_s와 fgets함수가 있다. https://blog.naver.com/dntkrl79/70180239572

 

3-2. gets_s()

char buf[20];
gets_s(buf, sizeof(buf));
gets_s(buf);		//배열은 템플릿에 의해 개별 배열 맞춤형 함수가 생성된다. (c++에서만 사용가능)

버퍼의 크기를 전달받아 그 크기를 넘어서는 입력에 대해 오류 메시지를 띄우고 프로그램을 강제종료시킨다.

 

3-3. fgets()

char buf[20];
fgets(buf, 20, stdin);		//stdin은 표준 입력 장치의 스트림. 보통의 경우 키보드 버퍼

fgets(버퍼에 대한 포인터, 문자열의 최대크기(\0포함), file)

-> \0을 제거하려면 str[strlen(str)-1] = '\0';   참고 : http://egloos.zum.com/lechocolat/v/441439

배열이면 sizeof를 써서 길이를 구하지만 포인터면 길이를 직접 입력한다.

버퍼 크기를 초과하면 이후의 입력은 무시한다. 

→ 입력 자료의 증발


fgets 함수와 scanf함수의 차이점

#include <stdio.h>
int main(){
	char data[101], data2[101];
	fgets(data, 100, stdin);
	scanf("%s", &data2);
	printf("%s%s", data, data2);
    return 0;
}

출력 결과

 

fgets는 공백문자가 포함되어 있는 문자를 저장할 수 있다.

scanf는 첫번째 단어까지만 저장된다.

 

따라서 공백문자가 있는 문장을 입력받으려면 fgets를 쓰면 될 것 같다.


 

4. getche()

conio.h

 

문자 전용 입력함수, 문자 한개만 읽어들임

 

- enter값을 입력받지 않는다. (키보드로 문자를 하나 입력하면 바로 입력이 끝난다.)

- 키보드 버퍼를 사용하지 않아 getchar()함수보다 속도가 빠르다.

 

 

4-2. getch()

 

getche()함수와 기능은 동일하다.

입력 문자가 보이지 않아 보안이 필요할 때 사용한다.

 

 


참고

표준입력함수 scanf, getchar, gets, sscanf

입력함수 getchar, getche, getch, gets, scanf

표준입력함수 getchar, getche, getch, gets, scanf

입력함수 gets, scanf, fgets 비교

'C 이론' 카테고리의 다른 글

[C] Bitwise 연산자  (0) 2021.05.19
[C] 이중 포인터  (0) 2021.05.02
[C 기초] return문  (0) 2021.03.27
[C 기초] 변수명 사용 규칙, 예약어  (0) 2021.03.23
[C 기초] 이스케이프 시퀀스  (0) 2021.03.23