lkc263   4년 전

첫번째:
제출을 하고나서 컴파일 에러 뜬 부분을 보니
(implicit declaration of function ‘gets_s’; did you mean ‘gets’? [-Wimplicit-function-declaration])
(번역: 함수의 암시적 선언 'gets_s'; 'gets'를 의미했는가? [-중요 기능 선언])
제가 이부분이 어떠한 의미인지 모르겠습니다.

두번째:

int num,count=1,sum=0;
char test[80];
scanf("%d", &num);
getchar();
for (int i = 0; i < num; i++) {
gets_s(test, sizeof(test));
for (int j=0; test[j] != '\0'; j++) {
getchar();
scanf("%c", &test[j]); <=======

<====이부분에서 scanf할 때 getchar이 없으면 입력이 되지 않고 넘어가게 됩니다. 제가 fgets에서는 개행문자 '\n'을 입력받기에 getchar형태를 사용하였는데, 이와 같은 scanf에서는 이상황에서 개행이 없으면 입력이 안되는지 궁금합니다.

surung9898   4년 전

첫 번째 질문의 경우, 다음에서 4번항목을 참고하시면 될 것 같습니다.

https://www.acmicpc.net/blog/view/52


두 번째 질문의 경우 어떤 질문인지 정확히 파악하기가 어렵습니다. 이 문제에서 gets_s로 한 줄 입력을 받은 후 다시 getchar과 scanf 함수로 입력을 받는 이유를 혹시 알 수 있을까요?

lkc263   4년 전

1.
gets_s는 컴파일러 GCC에 없는 함수여서
#define gets(s) gets_s(s) 를 사용하면 된다고 하셨습니다.

lkc263   4년 전

2.

이것을 디버깅 해보면 num값을 입력후 scanf("%c", &test[j]); 에서 입력이 안된후 넘어가게 됩니다. 그럼에 디버깅을 해본 결과 for문 시작하여 scanf를 만났을 때 자동으로 test[0]에 10'\n'가 들어가게 됩니다. 10'\n'어떤 의미를 가지고 있는 걸까요?

surung9898   4년 전

1.

전처리 매크로는 왼쪽의 것을 오른쪽으로 치환하여주는 것입니다. '#define A 30' 의 경우, 소스코드 상의 A가 30으로 치환되어 동작된다는 것입니다.


위의 소스코드의 경우 gets_s가 gcc에 없기때문에 제출하실 때는 gets로 제출하셔야하는데, 소스코드에서 gets_s를 사용하셨기 때문에 위의 'gets를 gets_s로 치환해주는' 매크로를 지우셔도 여전히 gets_s로 남아있어 컴파일 오류를 받으시는거라 추측됩니다.


그러므로, 매크로를 정의하신 후 gets를 사용하시면, 질문자님의 환경에서는 gets_s로 치환되어 작동하고, 제출하실 때 매크로를 제거하고 제출하시면 백준 온라인 저지의 채점환경에서는 gcc에 정의되어있는 gets함수로 작동되어 정상적으로 채점될 것입니다.

2.

이번 8958번 문제의 경우 입력이 다음과 같이 주어집니다.


5

OXOXXXXO

OOOOXXXO

...


주목할 점은, 제일 윗 입력에서 5와 함께 줄바꿈이 입력된다는 것입니다. 입력에서 주어진 줄바꿈, 즉 \n도 사라지지않고 입력값을 저장하는 버퍼에 저장됩니다. 즉, 다음과 같습니다.

5 \n O X O X X X X O \n O . . .

Int 형식의 입력값을 읽어들일 때의 경우에는 버퍼에서 정수값만 찾기 때문에, 이런 '\n'이 입력된 경우를 고려하지 않아도 큰 상관이 없습니다. 그런데 위 소스코드의 경우 12번째 줄에서 '문자'를 읽으려 하고있습니다. 이 경우 컴퓨터는 버퍼에서 문자값을 탐색하게 되는데, '\n'가 원래 의도한 'O'보다 먼저 입력되어 버퍼에 남아있으므로 '\n'을 읽어 test 배열에 저장하는 것입니다. 당연히 정상적인 동작을 기대하기는 어려워질 것입니다.


그러므로, 10번째 줄과 11번째 줄 사이에 아래의 소스코드를 한 줄 추가하시면 될 것 같습니다. 이렇게하면, 읽어들이려는 한 줄 사이사이에 존재하게되는 '\n'을 getchar로 처리하여 프로그램이 의도한 대로 동작할 것입니다.


좀 더 자세하게 알아보시려면 아래를 참고하시면 되겠습니다.
https://dojang.io/mod/page/vie...

lkc263   4년 전

1.
제가 실수를 했습니다. #define의 잘못 사용했습니다.

'제출하실 때 매크로를 제거하고 제출하시면 백준 온라인 저지의 채점환경에서는
gcc에 정의되어있는 gets함수로 작동되어 정상적으로 채점될 것입니다.' 라는 말씀이
어떠한 말씀일까요??
#define과 gets_s(test,sizeof(test))를 쓰지말고 gets(test)를 사용하라는 말씀일까요?
아니면 #define gets_s(a,b) gets(a,)를 쓰고나서 gets_s(test,sizeof(test))를 사용하라는 말씀일까요?

2.
아하! 맞습니다. scanf("%c"~)에 \n값도 읽게된다. 제가 실수 한 것같습니다.
또한 제가 잘못 생각한 것같습니다. for문안에 scanf("%c")를 넣으니 되게 안좋은 방법인것같습니다.

제가 2시간동안 말씀하신 내용을 천천히 읽어보니 문제가 해결되었습니다. 정말 감사합니다. (1번 질문의 궁금증만 해결되면 100%해결될 것같습니다.)

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