묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결홍정모의 따라하며 배우는 C언어
버퍼에 관한 질문 (수정본)
Q1) A가 출력되지 않는 이유는? 영상 (02:40)에 나오듯이 scanf의 %c는 한 문자만 읽을 수 있음으로, "A 3 2"을 입력시, A만 호출되고 \n는 버퍼에 남겨지는 상태를 볼 수 있습니다. 그로 인하여, 다음 출력문으로 입력하였던 "B 1 2"대신에 (\n 3 2)가 먼저 출력되는 것을 확인할 수 있습니다. 여기서 우리는 실제 scanf(%c %d %d)버퍼에 입력된 값이 ('A', 3, 2, '\n')임을 알 수 있습니다. scanf(%c %d %d) ↔ ('A', 3, 2, '\n') 그래서 다음과 같은 테스트를 진행해보았습니다. 영상(02:40)와 달라진 점은 기존에 \n자리에 s가 들어가고, 바로 그 뒤에 '\n'이 붙는다는 점입니다. 즉, 현재 scanf(%c) 버퍼에는 'A', 's', '\n'가 들어가 있는 것이죠. 그렇다면 총 (A 3 2), (s 3 2), (\n 3 2)순으로 while문이 출력되어야 할 것이라는 것이 저의 예상이었습니다. 그러나 위 결과물처럼 'A'는 생략되고, 's'가 출력되는 것을 확인할 수 있습니다. 한편, 버퍼에 남아있던 '\n'는 잘 출력되는 것을 확인할 수 있습니다. ----------------------------------------------------------------------------------- 2) 영상 (05:10)의 오해. // 자문자답 (선생님의 코드와 동일합니다. "* 3 5 빈칸"을 입력하셔서 한 번 반복되신 것으로 확인됩니다. 아마 사람들은 빈칸을 못보고 지나간 다음에 스스로 테스트한 것과 달라서 의문이 생길 수 있으니 다음 분들은 참고해주세요!) 영상에 나온 코드로 "A 3 2"를 입력하면 while문은 종료하게 됩니다. 왜냐하면 while문의 조건이 (c = getchar()) != '\n')인데, 질문1처럼 'A'과 함께 '\n'도 같이 입력이 되니, while싸이클을 한 번 돌고, 다시 올라오면 '\n'와 만나서 반복되지 않고 프로그램은 종료되는 것을 확인할 수 있습니다. 영상에서 보여진대로, 이는 while문 중간에 while (getchar() != '\n') continue;를 넣어주면 해결할 수 있습니다. 그 이유는 A 3 2를 입력하였을 때, getchar함수로 인하여 char c 변수에 'A' 문자 데이터가 저장되고, 버퍼에 남아있던 \n가 두 번째while문에서 읽혀지고 해당 while문 영역에서 벗어나면서 사라지기 때문입니다. ----------------------------------------------------------------------------------- Q3) \n는 어디로?? 본래, 저의 질문입니다. getchar을 청소해주는 while문을 주석처리해놓고, "# 3 2 빈칸"과 "% 1 2"를 입력해보았습니다. 얼핏보면 당연한 결과물이라고 생각할수도 있으나, 질문2에서 확인했다시피 "# 3 2" 싸이클이 끝나면 해당 while문은 '빈칸 3 2'을 한번 더 돌리고, '\n'을 만나서 종료되어야 했습니다. 즉, '\n'의 다음 순서인 "% 1 2"는 실행되어서는 안됩니다. "# 3 2 빈칸"을 입력하는 순간, 버퍼에는 ['#', 3, 2, '빈칸' '\n']가 저장이 됩니다. 이는 while문은 총 (# 3 2), (빈칸 3 2) (\n 3 2)를 돌릴 수 있는 경우의 수를 가지게 됩니다. 이 때, (\n 3 2)는 while문 조건에 의하여 종료되고 실행되지는 않아야 합니다. ***디버깅 테스트: 1. "# 3 2"가 출력된다. 2. 두 번째 싸이클인 "빈칸 3 2"이 시작되면 scanf함수가 실행이 됩니다. 3. scanf함수에 입력한 "% 1 2"는 버퍼에 들어가게 됩니다. 위 이미지처럼 char c변수에는 getchar함수로 인하여 '#'부터 '빈칸', '\n', '%'순으로 문자를 하나씩 버퍼에서 꺼내옵니다. 그 와중에 \n은 어디에서 제거가 된 것인가요?
-
미해결홍정모의 따라하며 배우는 C언어
질문) m1n_q님의 질문의 답변, 이해했는지 확인하고 싶어요.
안녕하세요. C언어는 질문도 상당히 많고, 길기도 하네요.. 질문드리기가 정말 실례되네요 ㅋㅋ... 저의 뇌피셜..;;이지만 제가 이해한 게 맞는지 확인하고 싶어요..ㅠ 처음에 while((c = getchar()) != '\n') 부분에서 " * 공백/3 공백 5 공백 "을 받은 것이 중요한 포인트입니다. 여기서 차곡차곡 순서대로 쌓인 버퍼에서 3과 5 앞의 공백은 각각 L-value 변수들을 구분하기 위한 공백입니다. 따라서 char의 버퍼에는 '*', 'space', '\n'가 들어가게 됩니다. 결과적으로 while은 총 (* 3 5), (space 3 5), (\n 3 5). 세 가지의 경우의 수를 갖게 됩니다. 아래 주석1) 이 설명에 잘못된 점이 하나 있습니다. 처음에 char버퍼에 *과 space와 \n가 있다고 했는데, 그렇다면 (%, 2, 2)가 출력되지 전에, \n를 만나서 while문이 실행되지 않아야 합니다.. \n가 중간에 어디선가에서 제거가 되는 것인데.. 또는 제가 완전히 잘못 이해했던 것일거에요 ㅋㅋ...(허탈) ------------------------------------------------------ 주석1) joy님 말씀대로라면 "두번째로 scanf가 실행되게 되었는데 버퍼엔 \n 만 남아있게되므로 scanf 에서 가져올게 없는 상태입니다. 근데 이때 \n는 버퍼에서 비워집니다." 이 때문에 sp, 3, 5에서 scanf를 호출할 때, \n는 사라지고 (%, 2, 2 + '\n')가 들어가니 %, 2, 2가 끝나고 while에서 \n를 만나게 되는 것 같습니다.