smkyu1919   2년 전

카운터 올리는 while문에서

현재칸이 빈칸이고 다음칸이 빈칸이 아닐 때 카운터를 올리도록 해놨습니다.

개인 테스트로는 이상이없었는데 백준 컴파일에서는 틀렸다해서

타 카페에서 질문을 해보니

현재칸 빈칸이고 다음칸이 마지막열인 NULL 값 일때도 카운터를 올리도록 설정이 되어있다해서

마지막에 배열의 마지막열 앞이 빈칸이고 마지막열이 NULL 값일 때도 카운터를 한개 내리기로 설정했는데도

틀렸다고 뜨네요... 어떻게해야할지 좀 잡아주셨으면 감사합니다.


djm03178   2년 전

이 문제에서는 입력의 끝에 \n가 들어오지 않습니다. 즉, fgets 함수라고 해서 뒤에 \n을 붙여주지는 않습니다.

그걸 고려해서 수정해보세요.

smkyu1919   2년 전

djm03178 님 그 말을 이해를 못하겠습니다. 다시 한 번 설명부탁드려요.


답변주신것처럼 문제에서 입력에 \n이 들어가지 않는다는 것을 알고있습니다.

그리고 fgets 함수가 문자열 끝에 개행을 달고 있다는 걸로 알고 있습니다. 그렇기에

해당 1152문제가 개행을 포함시키는게 아니기 때문에 (1)abc[strlen(abc)-1]='\0' 을 넣어 개행을 NULL값으로 바꾸었고

저 방식으로 하면 [빈칸 > 빈칸을 제외한 아무거나] 일 시 카운터가 추가되는데

마지막에 빈 칸 > NULL 값도 카운터가 추가되기에

배열길이가 하나 줄은(1)

abc[strlen(abc)-1] 값이 빈칸이고  abc[strlen(abc)] 값이 NULL 값일 때의 불필요한 추가 카운터 값을 삭제 시키는 식으로 진행했습니다.


fgets를 이용한 저 식을 유지를 할 때 몇 번째 줄을 수정해야 되는지 그 부분을 정확히 집어주시면 감사하겠습니다.

djm03178   2년 전

fgets는 개행 문자가 입력에 없으면 멋대로 개행을 추가하지는 않습니다. 즉, 저 코드대로라면 abc 라는 문자열이 입력되었을 때 abc\0가 들어가는 것이고, 여기에 abc[strlen(abc)] - 1 = '\0'을 하면 ab\0이 됩니다.

djm03178   2년 전

http://en.cppreference.com/w/c...

"Reading stops if end-of-file occurs or a newline character is found, in which case str will contain that newline character."

EOF가 나타나거나, 개행 문자가 나타나면 "그" 개행 문자를 포함한다 라고 되어 있습니다. 즉, EOF로 끝나면 개행 문자가 포함이 안 됩니다.

smkyu1919   2년 전

이 부분을 이해를 잘 제가 못하는 것 같습니다.

fgets 함수에서 입력을 할 때 개행을 넣지말고 EOF로 끝나게 하라고 하셨는데

입력 시 어떻게 개행없이 fgets에 값을 집어 넣을 수 있는지 알려주시면 감사하겠습니다.

말씀주신 부분은 fgets 입력 시, 개행 입력을 하지 않고 EOF로 끝나게 하라는 걸로 저는 이해하고 있습니다.

http://egloos.zum.com/lechocol...

fgets함수를 여기서 배웠습니다. 내용 중에 fgets 함수는 enter로 입력하는 순간 바로 개행입력이 되어 배열에 포함된다는 내용이었고

개인적으로 소스로 확인해봐도. 개행문자가 삽입이 될 수 밖에 없는 구조인거 같은데...


이 부분 한번더 설명 부탁드릴께요. 제가 이해가 많이 부족해서 자세한 설명 부탁드립니다.

그리고 이 부분보다 djm03178님께서 위에 제 코드 소스에서 개선해야될 부분이 어딘지 명확하게 집어주시면 제가 그 부분 수정하고

방금 말씀해주신 부분을 더 빨리 이해할 수 있을 것 같습니다.

djm03178   2년 전

일단 계속 착각하고 계시는 부분이 "내용 중에 fgets 함수는 enter로 입력하는 순간 바로 개행입력이 되어 배열에 포함된다는 내용이었고" 라고 하신 부분인데, 일반적으로 항상 개행 문자가 들어갈 것처럼 보이는 건 우리가 입력의 끝에 엔터를 쳐주기 때문일 뿐입니다. 저 채점 서버에서는 아무도 엔터를 쳐주지 않습니다.

그리고 문자열의 끝에 EOF를 넣으라는 게 아니고, fgets 함수가 EOF, 즉 파일의 끝을 만났기 때문에 종료가 되었다는 뜻입니다.

예시를 들어볼게요. 우리가 fgets 함수에 직접 "abc"라는 문자열을 주려면 이렇게 해야 됩니다.

abc[엔터]

여기서는 문자열의 끝에 [엔터]가 있습니다. fgets 함수는 이 [엔터]까지 모두 포함해서 목적지에 넣어줍니다. 따라서 strlen(s)는 4가 됩니다.

하지만, 채점 서버에서는 이렇게 되어 있습니다.

abc[아~무것도 없음]

즉 들어온 입력은 a, b, c 이 세 글자로 끝입니다. 그 후는 모든 입력이 끝난 상황이고, 이를 fgets 함수는 EOF를 만났다고 하는 것입니다. 그러므로 이 시점에서 fgets 함수는 목적지에 abc만 넣어줍니다. 그래서 strlen(s)는 3입니다.

이 부분은 손수 실행해서 키보드로 입력을 줘서는 테스트하기 어렵고, 파일을 하나 만들어서 그 안에 내용을 넣은 뒤에 (마지막에 개행하지 말고) 이 파일을 대신 stdin이 읽어들이게 해서 실행해봐야 알 수 있습니다. 그렇지 않다면 그냥 논리적으로 이해하면서 하는 수밖에 없습니다.

smkyu1919   2년 전

아.. 결국 studio에서 fgets 연습할 때 enter 치고 할 때와, 채점 서버에서 fgets를 돌릴 때 개행 적용이 되고 안되고의 차이였네요..

자세한 설명 정말 감사합니다.

그러면 studio에서 나오는 값이 정확하다고 정답이아니라(지금 상황에선) 채점 서버 기준으로 맞춰야 하는 거였군요.(fgets로 개행입력 enter없이 바로 값입력되는)


djm03178님께서 말씀하신데로 채점서버 기준으로 적용해서(strlen(abc)값이 마지막열 앞에 개행 값이 포함안된다는 전제하에 )

아래 코드만들어서 돌렸는데 한 번더 채점중에 틀렸다고 하네요.

괜찮으시다면 한 번더 봐주실 수 있으십니까?


smkyu1919   2년 전

엇 잘못적었습니다. 다시 소스 수정해서 올려요.

djm03178   2년 전

이런 케이스가 있는지는 모르겠지만, 아무것도 입력이 안 됐을 때 1이 출력되는데 수정해보세요.

smkyu1919   2년 전

아무것도 입력안됐을 때 1 나오는 것도 아까 말씀해주신거에 포함해서

채점서버에서는 0이되도록 인식하고 했는데도 잘 안되네요.. 몇 시간을 이문제에 투자했는데 ㅠㅠ

도움주셔서 정말 감사합니다. 좋은 것 배우고 갑니다!

다음에 또 모르면 답변해주시면 감사하겠습니다. 밤새서라도 이건 마무리지어야겠네요...

kigsma3709   2년 전

이미 해결 하셨겠지만 말씀드릴게요.

이 문제에서는 왠지 모르겠습니다만 개행문자가 들어갑니다.

소스코드에서 개행문자가 들어간다는 가정하에 만든 경우에서는 맞다고 나왔는데 저 분 말씀대로 개행문자가 없는 경우로 만드니까 틀렸다고 나오네요.

이 문제는 마지막에 개행문자가 들어갑니다.

djm03178   2년 전

https://www.acmicpc.net/board/... 에 작성했듯이, 개행 문자가 있는 케이스도 있고 없는 케이스도 있는 것으로 보입니다. 처리한 방법에 따라서는 어느 쪽으로 가정해도 틀리게 나올 수 있습니다.

kigsma3709   2년 전

이번 문제는 있는 케이스네요

djm03178   2년 전

이번 문제가 있는 케이스도 있고 없는 케이스도 있다는 뜻입니다. 즉, 일관성이 없는 거죠. 그래서 수정을 요청한 거고요.

kigsma3709   2년 전

아, 그런가요.

그렇다면 사용하는 함수에 따라서 개행문자가 있을 수 있고 없을 수 있다 이건가요?

djm03178   2년 전

fgets의 경우는 개행 문자가 있으면 그 개행 문자까지 포함해서 넣어주므로 결과 문자열에 개행 문자가 있을 수도 있고 없을 수도 있죠. getchar 등으로 한 문자씩 받아오더라도 마찬가지고요. 다만 gets 함수는 개행 문자가 있어도 그냥 버려주기 때문에 영향을 주지 않고요.

kigsma3709   2년 전

그렇군요.

저,그런데 다루던 주제와는 관계없습니다만 strupr함수가 이 사이트의 컴파일러에서 사용이 안되는 것 같은데 어떻게 바꿔서 써야할까요?

djm03178   2년 전

반복문 돌리면서 toupper로 한 글자씩 대문자화해주시면 됩니다.

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