sksioi1   6년 전

스택문제를 accept 받았습니다. 다만, 제가 궁금한 점은 scanf()함수를 사용하여 개행문자로 풀었을 때는 accept되고 

fgets를 이용해서 풀었을 때는 계속 틀렸다고 뜹니다. 

예제 결과는 두개다 정확히 나옵니다. 하지만 왜틀렸는지 어디서 오류가 났는지  궁금합니다. 

djm03178   6년 전

일단 strncpy 함수가 문자열의 끝을 만나기 전에 최대 문자 수 한도에 부딪히면 끝에 널 문자를 안 넣어주는데, 여기서 오류가 안 나는 건 시스템상의 차이인 것 같고요 (VS 2017 디버그 모드에서는 예제 입력에 대해 아무 출력을 안 했습니다.)

그 부분을 수정해서 돌려봐도 마지막 한 줄이 나오지 못하는데, 끝까지 정확하게 확인해보신 건지 모르겠습니다. 첫 줄 scanf 입력 후 개행 문자가 버퍼에 남아서 이 개행 문자만을 fgets가 한 번 읽어버리기 때문에 명령어 수가 하나 적게 수행되어버립니다.

sksioi1   6년 전

답변 감사합니다.


하지만 "첫 줄 scanf 입력 후 개행 문자가 버퍼에 남아서 이 개행 문자만을 fgets가 한 번 읽어버리기 때문에 명령어 수가 하나 적게 수행되어버립니다." 이 부분이 정확하게 이해가 되지 않습니다.

혹시 조금 더 구체적으로 말씀해주실 수 있을까요? ㅠㅠ...

djm03178   6년 전

scanf에 %d를 전달하면, 이 scanf는 화이트스페이스 (공백, 개행 문자, 탭) 등을 무시해버립니다. 특히 입력이 끝나고 난 뒤에 오는 화이트스페이스들은 그대로 입력 버퍼에 남겨둡니다.

버퍼에 남겨둔다는 말은, 다음 입력 함수가 호출되었을 때 그 함수가 그 내용을 먼저 읽는다는 뜻입니다. 예시 입력을 예로 들면 첫 줄의 입력은 그냥 14가 안이라 14\n인데, scanf는 오로지 14만 읽고 빠져버리기 때문에 \n은 여전히 입력 버퍼에 남아있고, 이는 다음 루프에 있는 fgets가 읽어버립니다. fgets는 개행 문자를 만나면 그 자리에서 종료하므로, str1에는 개행 문자만 남아버리고 hotStack 함수가 호출되어버리는데 이는 아무 역할도 안 합니다. 그렇게 루프 1개가 낭비되었기 때문에 원하는 횟수보다 1번 적게 명령을 수행하는 것처럼 보이게 됩니다.

sksioi1   6년 전

너무 감사합니다 ㅠㅠ!

댓글을 작성하려면 로그인해야 합니다.