shgusgh9485   1년 전

아래 코드는 맞은 코드입니다.

근데 궁금한 것이 배열의 범위를 100001로하면 틀렸다고 나오는데 이해가 가질 않아서 질문드립니다.

문제에서 최대 문자열의 수는 100000이라고 했고 fgets는 마지막에 공백문자를 넣기에 100001을 범위로 잡으면 된다고 생각했는데 틀렸다고 뜹니다. 이유가 뭘까요..?

wak8835   1년 전

gets 와 헷갈리신 것 같습니다.

gets는 '\n'이 있는 경우에 \0 로 치환해서 저장하지만, fgets는 '\n'까지 입력을 저장하고, 그 후에 \0을 추가하여 스트림에 저장합니다.

shgusgh9485   1년 전

아 그렇군요. 근데 그 후에 \0을 추가해도 배열의 범위가 100001이어도 상관없지 않나요...?

wak8835   1년 전

이 문제에 대한 문자의 개수가 100,000개라고 한다면 + 1개 ('\n') + 1개 ('\0') 이므로 char[100002] 공간을 필요로 합니다.

shgusgh9485   1년 전

저도 처음에는 그렇게 생각했는데 이렇게 횡설수설하게 된 이유가 아래와 같은 사유 때문입니다...

아래코드는 9093문제입니다. 여기서는 문제에서는 문자의 개수가 1000이 최대라고 하였습니다. 하지만 1001로 배열의 범위를 설정하여도 정답이라고 떴습니다. 이 문제도 틀렸다고 떠야하며 1002로 수정해야 맞았다고 떠야되는데 왜 저 문제는 맞는 걸까요?? 혼란스럽네요 ㅠㅠ

wak8835   1년 전

@shgusgh9485 

확인해보니 9093번 문제에 문자열 길이가 1000인 테스트케이스가 존재하지 않네요.

우연히 통과된 것으로 판단됩니다.

shgusgh9485   1년 전

아 그런가요...? 문제에 있지 않나요?? 

암튼 그럼 알려주신 개념을 가지고 입력받는 문자열에 2칸을 더 더해서 앞으로는 범위를 설정해주면 되겠네요 감사합니다! ㅠㅠ

shgusgh9485   1년 전

저 혹시 추가적인 질문으로

#include

int main() {
char str[5];
fgets(str, 5, stdin);
printf("%s", str);
return 0;
}

이 코드에서 

abc를 입력하면 말씀하신 것처럼

abc+ ('\n') +  ('\0')가 입력되잖아요 근데 

abcd도 입력이 되던데 이런 경우는 뭔가요...?

wak8835   1년 전

제가 작성자님께서 올려주신 코드부터 해석을 잘못해서 일부 오해할만한 정보를 드린 것 같습니다.

위에 드린 정보들은 맞는 내용이지만 구체적으로 상위 문제가 틀린 이유는 다른 이유에서 였네요.

정확히 정리 후에 다시 댓글 달아드리겠습니다.

shgusgh9485   1년 전

아... 그런가요? 알겠습니다 ㅠㅠ

wak8835   1년 전

@shgusgh9485

수정한 소스코드 먼저 올리겠습니다. 

위의 설명은 추가적으로 댓글로 계속 달도록 하겠습니다.

wak8835   1년 전

모든 정보에 대한 내용을 종합하기 위해 근본적인 fgets 함수에 대한 원형과 설명을 확인해보자면 다음과 같습니다.

https://www.ibm.com/docs/ko/i/...

#include <stdio.h>
char *fgets (char *string, int n, FILE *stream);

fgets 함수는 현재 stream (작성자 분은 표준입력인 stdio) 위치에서 줄 바꿈 문자 (\n)가 들어오기전, 또는 읽은 문자수가 n-1과 같을 때까지 문자를 읽습니다.

-> 즉, 만약 n-1 보다 stream 에 값이 많은 경우에는 이를 다 못읽고 놔두게 된다는 뜻이겠죠.

이 결과에 끝에 널 문자인 (\0)을 추가합니다.

즉, 작성자분의 기존 char[100001] 배열에 fgets 함수로 문자열을 넣게 된다면 최대 문자열인 100,000을 넣을 때와 그 보다 적은 문자열을 넣을 때 두가지로 나뉘게 됩니다.

1. 100,000자 보다 적은 문자열을 넣게 될 때

preview

2. 100,000자 문자열을 넣게 될 때 (개행이 끝에 있는 경우에는 n-1를 초과하게 되므로 읽지 못하고 놔두게 되므로...)

preview

즉, 이 2가지 형태가 되므로 15~18번 라인을 추가하여 문자열 길이를 재확인 해주셔야 합니다.

(*strlen 함수는 널 문자(\0)의 위치를 문자열의 끝으로 인식하여 반환합니다.)

shgusgh9485   1년 전

와... 드디어 이해했습니다. 저런 그림구조를 보고싶었어요 ㅠㅠ 

차라리 앞으로는 원하는 문자열의 길이에 2개 더해주는 게 날 거 같네요... 

그동안 이것때문에 문제를 맞춰도 찝찝하고 헷갈렸는데 감사합니다 ㅠㅠ

wak8835   1년 전

나머지는 위에 드린 정보의 재확인과 질문 내용을 다시 정정해드립니다.

1. gets는 개행('\n')이 있는 곳까지 입력으로 받아들이고, '\0' 로 치환해서 저장 O

2. fgets는 개행('\n')이 들어오기 전 또는 읽은 문자수가 n-1과 같을 때까지 입력으로 받아들이고, 그 끝에 '\0'를 추가하여 저장 O

3. 9093번 문제는 문자열 길이가 1,000자인 케이스가 존재하지 않음 ( 런타임익셉션 테스트로 체크 )

추가적으로 문자열 버퍼를 담을 메모리가 존재하는 경우 (최대 문자열을 담을 만한 문자열 배열이 존재하는 경우) gets 를 쓰는 것이 '\0' 처리에 번거로움이 없을 것이지만,

다양한 크기의 입력 또는 파일에서 순차적 처리가 필요한 경우에는 fgets를 쓰시는 것이 더 용이하실 것으로 보입니다. 

이는 개인적인 의견이며 코드스타일 등의 성향도 있으므로 작성자분께서 원하시는 상황에 적절히 활용하시면 될 것 같습니다 :)

shgusgh9485   1년 전

네 귀찮으실텐데 감사드립니다 ㅠ

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