이전에 입력 버퍼를 비워주기 위해 getchar()을 사용했었다.
실제로 입력 버퍼를 비우는데 getchar()을 쓰면 편한데, 잘 알고 넘어가야될 점이 있다.
getchar() 함수는 문자 하나를 읽어드리는 함수다.
다음과 같이 scanf 함수에 개행처리 \n를 해줬을 때, getchar();을 버퍼를 비우는 용도로 쓰면 안 된다.
scanf("%d\n", &N); // 개행 처리
char ch = getchar();
printf("getchar이 받아드린 값은 %d", ch);
char * str = malloc(sizeof(char) * 12);
scanf("%[^\n]s", str);
getchar();
printf("\n str is %s", str);
scanf 함수에 이미 개행처리가 되었기 때문에 사용자가 정수값 N을 입력하고 엔터를 쳐서 N 값을 저장한 다음, push를 입력한다고 하자. scanf 함수의 \n 때문에
push에서 p는 getchar()으로 받아들였다.
getchar으로 인해서 문자열 str은 p가 잘린 값 ush만을 받게 된다.
백준 2161에서, scanf 함수에 개행처리를 해준다면 다음과 같은 오류가 난다.
int N;
scanf("%d\n", &N);
//추후에 printf로 출력, scanf 사용 안함
프로그램 실행 시, 엔터를 아무리 눌러도 안 끝난다. 그래서 Ctrl + Z를 해주니 끝났다.
여기서 getchar()을 해서 버퍼를 비우려 했다. 엔터를 아무리 쳐도 종료가 안되는데, Ctrl+Z를 두번하니 종료가 되었다. getchar이 받는 값은 -1이다.
7 엔터하고 바로 s를 치면 getchar은 s를 받긴 받는다.
7 치고 엔터 엔터 엔터... 반응이 없어서 s를 누르니 종료 되어서 getchar은 s를 받았다고 한다.
아무래도 숫자 입력 후 엔터 치고 다른 문자를 치기를 기다리는데 계속 엔터가 들어와서 getchar은 아무것도 못 받았다 생각하는 것 같다. 그러고 s를 누르니 그제서야 getchar이 s를 받았다고 본다.
만약 scanf 함수를 개행처리를 안 하고 getchar을 한다면?
getchar은 Line Feed(아스키 코드 10)을 받는다.
int N;
scanf("%d", &N);
char ch=getchar(); //getchar 유무에 따라서 달라진다. //here getchar value??
char* str = malloc(sizeof(char) * 12);
printf("getchar이 받아드린 값은 %d\n", ch);
scanf("%[^\n]s", str);
getchar();
printf("\n str is %s", str);
getchar()은 엔터를 읽어드린다. 그래서 아스키코드 값이 10이 나온다.(Line Feed)
결과를 보고 비교를 하자.
scanf 함수에 \n을 넣어주나 안 넣어주나 숫자를 치고 엔터를 쳐야되는 것은 동일하다. Command 창에 문자열을 입력하는공간도 모두 둘째줄이다. 다만 getchar 함수가 무엇을 저장하는지에 따라 다르다.
scanf 함수에 개행 처리를 한 경우, getchar은 push에서 첫 글자 p를 받고,
scanf 함수에 개행 처리를 하지 않은 경우, getchar 함수는 개행 문자 \n을 받는다. 따라서 getchar은 아스키코드 10의 값을 가진 LF를 받은 것이다.
위 두번째 경우에는 scanf 함수를 두번 써서, 한번은 숫자를 받고 한번은 문자열을 받는데..
scanf 한 번 써서 숫자만 받으면 getchar이 필요 없다.
int N;
scanf("%d", &N);
숫자 하나만 입력받는 2161번에서 scanf 함수에다 개행처리를 안 하고, getchar()을 안 해도
잘만 나온다. 아무래도 숫자 하나만 받으니, 숫자를 받고 버퍼를 비워줄 필요가 없어보인다.
물론, 다음과 같이 뒤에 getchar을 한다 해도 엔터를 getchar이 받는 것이기 때문에 괜찮다.
결론적으로 scanf를 한 번 쓸 때는 scanf("%d", &N);만 써도 된다.(그 뒤에 getchar을 써도 괜찮다.)
숫자 N만 받고 싶은데 scanf("%d\n", &N); getchar();을 하면 숫자 N 하나가 아닌 다른 값을 받아야 끝나서 주의해야 된다.
getchar() 함수가 scanf 함수로 값을 받고, 버퍼를 비우는데 유용하긴 하나 주의해서 사용해야 된다고 본다.
숫자 하나만 받는데 scanf("%d\n", &N);면 ctrl+Z로 종료해줘야 되는 문제점이 있다.
여러 개의 숫자, 문자를 받는 코드 예시는 다음과 같다.
int main(void)
{
StackInit(&s1);
StackInit(&s2);
char str[100001]; //처음에는 10만개 문자!!
int M;
scanf("%s", str);
getchar();
int N=strlen(str); //문자열 길이는 N
scanf("%d", &M); //명령어 개수
getchar();
FirstText(str, N);
for(int k=0; k<M; k++)
{
char c1, c2;
scanf("%c", &c1);
getchar();
if (c1 == 'P')
{
scanf(" %c", &c2); //%c 앞에 공백을 포함해야된다. 특정문자 다음 스페이스와 c2를 둘 다 인식해야 되기 때문
getchar();
// printf("%c AND %c\n", c1, c2);
SPush(&s1, c2);
}
scanf 함수에 \n을 안 넣어준 코드다. scanf 함수 사용 후에, getchar을 하면 잘 돌아간다.
scanf("%d", &N); getchar();
scanf 함수 일부에 \n을 넣어주고 getchar을 지워버리면 어떻게 동작할까?
scanf 함수의 \n이 개행처리를 해주고 바로 다음 scanf 함수의 문자를 받게 해서 잘 동작한다.
78행 scanf("%s\n" , str); 81행은 scanf("%d\n", &M);
이처럼 다양한 예를 파악해서 getchar을 쓸지말지 결정해야 한다.
특정 문자를 입력했을 때, 문자 하나 더 받기 (0) | 2022.07.03 |
---|---|
c언어 mistake_출력형식 (0) | 2022.07.01 |
2차원 배열로 문자열 받기(동적할당x) (0) | 2022.07.01 |
댓글 영역