• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    미해결

22:14 구간 예제 질문

21.07.05 16:32 작성 조회수 170

0

예제의 내용이 엔터키와 입력값이 없는 경우가 아닌이상 

문자열을 계속 받는 코드잖아요.

그런데 입력값을 NULL, null, '\n', '\0'

요 4개를 입력해도 무한루프가 종료되네요.

어떠한 이유때문에 이런건지 알수 있을까요?

답변 1

답변을 작성해보세요.

5

안소님의 프로필

안소

2021.07.06

디버깅을 해보니 이런 현상 때문이네요!

NULL 을 입력하면 크기 5인 small_array 에  { 'N', 'U', 'L', 'L', '\0' } 이 들어갑니다. 즉, 입력 버퍼에서 차례로 꺼내서  small_array[0] 첫번째 원소부터 하나 하나씩 채워 주는 것입니다.

그런데 여기서 주의해야할 점은 fgets 는 개행문자까지도 입력 버퍼에서 꺼내와 입력을 받는 함수라는 것입니다. 따라서 원래라면  { 'N', 'U', 'L', 'L', '\n' } 이 되는 것이 맞겠지만, C언어에서 문자열을 표현할 땐 문자열 뒤에 꼭 \0 가 붙어야지만 문자열 끝이 어딘지 알 수 있기에, 배열크기가 n 이라면 딱 n - 1 크기까지만 입력을 받습니다. 즉, small_array[0] ~ small_array[3] 에만 입력한다는 것입니다. 끝에 나머지 하나인 small_array[4] 는 \0 이 되어야 하니까요! 그러니까 small_array 의 크기는 5지만 앞에 4개의 자리에만 입력을 받는다는 것입니다. 

따라서 { 'N', 'U', 'L', 'L', '\0' } 가 되며 \n 은 아직 입력 버퍼에 남아있는 상태입니다. 그것도 버퍼에서 가장 첫번째로 앞에 있는 상태이기에 다음 반복에서 첫번째로 빠져나오게 될 것입니다.

그리고 이제 다음 while 문 반복을 하게 되는데 fgets 는 자연스럽게 입력 버퍼에 남아있던 \n 을 가져와 small_array[0] 에 저장을 합니다. 즉,  { '\n', 'U', 'L', 'L', '\0' }  상태가 됩니다. 이는 while 문 종료 조건에 해당합니다. (small_array[0] == '\n' 이므로) 따라서 더 이상 while 문이 돌지 않고 종료되는 것입니다.

다른 예시도 다 같을 것이라고 생각됩니다. 그래서 질문자님께서 주신 예시 아니더라도 4 자리의 문자열을 입력하면 똑같은 현상이 발생하네요!!! (질문자님 예시도 전부 문자열 4자리구요)  small_array 의 크기가 5인 것과 관련이 있습니다. 즉, 결론적으로 \n 이 입력 버퍼 남아있는 것 중 가장 첫번째가 되는 케이스는 다음 반복에서 small_array[0] 에 입력되기에 종료되는 현상이 발생한다고 생각하시면 됩니다. 만약 이 코드를 실무적으로 쓰겠다고 한다면 이런 케이스가 발생하지 않도록 설정해주어야 할 것 같네요! 의도치 않은 결과니까요