작성
·
326
0
이정도까지만 작성한 후, 처음 엔터를 입력했을 때 정상적으로 반복문을 빠져나가 프로그램을 종료하는지 알아보기 위해 실행해보았습니다.
컴파일 에러는 없었고 정상적으로 빌드되어 실행되었는데,
왜 런타임 에러가 발생하는지 이유를 모르겠습니다.
[수정] 코드를 전체 다 작성했음에도 똑같이 런타임 에러가 발생합니다..ㅠㅠ
#define CRTSECURE_NO_WARNINGS
#include <stdio.h>
#include <limits.h>
#define MAX_TITLE 40
#define MAX_AUTHOR 40
#define MAX_BOOK 3
char* s_gets(char* st, int n)
{
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
find = strchr(st, '\n');
if (find)
* find = '\0';
else
while (getchar() != '\n')
continue;
}
return ret_val;
}
struct book
{
char title[CHAR_MAX];
char author[CHAR_MAX];
float price;
};
int main()
{
struct book bk[MAX_BOOK] = {"Empty", "Empty", 0.0f};
int count = 0;
int i;
for (i = 0; i < MAX_BOOK; i++) {
printf("Input a book title or press [Enter] to stop\n");
if (s_gets(bk[i].title, MAX_TITLE) == NULL) break; //EOF를 만나 NULL을 반환했을 때 (예외처리)
if (bk[i].title[0] == '\0') break;
printf("Input the author.\n");
s_gets(bk[i].author, MAX_AUTHOR);
printf("Input the price.\n");
int flag = scanf("%f", &bk[i].price);
while (getchar() != '\n') continue; //getchar() != '\n'는 입력 버퍼 내의 개행을 지우는 역할. 꺼내어서 비교? == 버퍼에서 소거
if (i == 2)
printf("No more books.\n");
count++;
}
if (count > 0)
{
printf("\nThe list of books:\n");
for (i = 0; i < count; i++)
printf("\%s\" written by %s: $%.1f\n", bk[i].title, bk[i].author, bk[i].price);
}
else
printf("No books to show.\n");
return 0;
}
답변 1
1
고민해보고 원인을 찾았습니다.
헤더파일 <string.h>를 포함하지 않았습니다.
포함시켰더니 정상적으로 작동은 잘 됐는데..
그렇다고 하더라도
1. <string.h>를 포함하지 않았음에도 strchy( )함수가 포함된 것을 컴파일러가 걸러주지 못한 이유는 무엇인가요?
2. 만약 내부적으로 어떠한 라이브러리에 링킹이되어서 strchr( )함수가 있음에도 위처럼 정상적으로 빌드가 되었다고 하겠습니다.
그렇다고 하더라도 strchr( )함수는 char* 타입을 반환하므로 수정이 가능하지 않나요?
따라서 초기값 "Empty"를 수정할 수 있으니까 새로운 입력값에서 \n을 찾아서 포인터를 find에 대입하고, 그것을 \0으로 바꿔줄 수 있는 것일텐데..
왜 정상적으로 빌드되었는지 모르겠습니다.
*저는 visual studio2022버전을 사용중입니다.
컴파일러마다 차이가 있는건 아닐까 싶습니다.
가령 제가 사용하는 gcc 컴파일러는 바로 컴파일 에러를 발생시켜줍니다.