fgets vs scanf
scanf : 문자를 입력 받을 때 공백문자(' ', '\n', '\t') 만나기 전까지만 입력 받을 수 있다.
그 이유는 scanf 는 stdin 에서 데이터를 얻어오기 때문에 stdin 에서 위 세 개의 문자열을 만난다면, 아 여기서 입력은 끝이구나 하고 입력을 종료해버리기 때문이다.
printf("30 자 이내의 문자열을 입력해주세요! : ");
scanf("%s", words);
// 실행결과
30 자 이내의 문자열을 입력해주세요! : what is your name
문자열 : what
fgets : 스트림에서 문자열을 받아서 (num - 1) 개의 문자를 입력 받을 때 까지나, 개행 문자나 파일 끝(End-of-File) 에 도달할 때 까지 입력 받아서 C 형식의 문자열로 저장한다. 개행 문자는 fgets 로 하여금 입력을 끝나게 하지만 이 문자 역시 str 에 저장한다.
1) NULL 문자는 자동적으로 마지막으로 입력받은 문자 뒤에 붙는다.
2) 'Enter' 는 버리고 null 문자를 마지막에 넣는다.
#include <stdio.h> // C++ 의 경우 <cstdio>
char* fgets(char* str, int num, FILE* stream);
// 실제사용
fgets(string, LENGTH, stdin);
num - 1 만큼만 문자열을 입력받는다.
Scanf 사용할 때 유의해야 할 점.
/* 이상한 scanf */
#include <stdio.h>
int main() {
int num;
char c;
printf("숫자를 입력하세요 : ");
scanf("%d", &num);
printf("문자를 입력하세요 : ");
scanf("%c", &c);
return 0;
}
// 실행결과
숫자를 입력하세요 : 1
문자를 입력하세요 :
결과에서 볼 수 있듯이 여기서 이상한 부분은 숫자을 입력하고 문자를 입력 받아야하는데 그냥 그대로 문자열 입력이 종료된다는 것입니다. 왜?
여기서 Buffer에 대한 이해가 조금 필요한데,, 숫자를 입력을 받고 Enter를 누를텐데 (그래야 다음 입력을 받을 수 있으니까)
근데 이때 컴퓨터는 Buffer에 Enter 까지 저장하게 됩니다.
scanf("%c", &c);
그리고 나서 위의 코드가 실행이 되면 %c 는 이유를 불문하고 stdin에서 딱 한 개의 문자만을 가져오게 됩니다. 만약 stdin에 아무것도 없다면 사용자의 입력을 기다리겠지만 무엇가가 있다면 냉큼 가져올 것이다. 그런데 위에서 Enter를 입력해서 Buffer에 엔터가 들어가 있으므로 이를 c 변수에 저장하게 된다. 즉, c 에는 사용자의 입력을 받지도 않고 \n 을 집어넣은 것이다.
%s 나 %d 그리고 모든 데이터를 입력 받는 형식은 버퍼에 남아있는 공백 문자에 신경쓰지 않고 사용할 수 있지만
%c 를 사용할 때에는 버퍼에 무엇이 남았는지 잘 고려해야한다.
그렇다면 어떻게 해결하면 될까?
여러 방법이 있지만 나는 %c 앞에 한칸을 띄워서 해결하는 것이 가장 편리하고 쉬웠다.
scanf(" %c", &c);
또는 getchar() 를 사용할 수 있다.
/* getchar 함수 이용 */
#include <stdio.h>
int main() {
int num;
char c;
printf("숫자를 입력하세요 : ");
scanf("%d", &num);
getchar(); // getchar() 사용!
printf("문자를 입력하세요 : ");
scanf("%c", &c);
return 0;
}
요약 (Summary)
그냥 %c 사용하지말고 %s 사용해라
'C 언어' 카테고리의 다른 글
C 언어 0.05 - 포인터 ( pointer ) (0) | 2021.10.30 |
---|---|
C 언어 0.04 - 배열 ( array ) (0) | 2021.10.30 |
C 언어 0.03 - 문자열 ( string ) (0) | 2021.10.27 |
C 언어 0.01 - 변수 (variable) (0) | 2021.10.27 |
[INTRO] - 왜 C언어를 알아야 할까? (0) | 2021.10.26 |