모두의 코드 커뮤니티

C언어 구조체 포인터 쓰레기값

#include <stdio.h>
int add(int* max_num, struct reg_books* pbook);
struct reg_books {
char name[30];
char auth[30];
char publ[30];
int borrow;
int book_num;
};
int main() {
struct reg_books book[100];
int max_num;
int menu;

printf("                    도서 관리 프로그램 \n");

while (1) {
	printf("1. 책 추가하기 \n");
	printf("5. 프로그램 종료하기 \n");
	printf("원하는 기능의 번호를 누르세요 : ");
	scanf_s("%d", &menu);

	if (menu == 1) {
		add(&max_num, book);
	}
	else if (menu == 5) {
		return 0;
	}
	else {
		printf("올바른 명령이 아닙니다. \n");
	}
}
return 0;

}
int add(int* max_num, struct reg_books* pbook) {

printf("== 책을 추가합니다 \n");
printf("저장할 책의 번호를 눌러주세요 : ");
scanf_s("%d", max_num);		
printf("현재 저장할 책의 번호는 %d번 입니다. \n", *max_num);

printf("책의 제목을 입력해주세요 : ");
scanf_s("%s", &pbook->name[*max_num], 30);	
printf("책의 저자를 입력해주세요 : ");
scanf_s("%s", &pbook->auth[*max_num], 30);
printf("책의 출판사를 입력해주세요 : ");
scanf_s("%s", &pbook->publ[*max_num], 30);

    return 0;

}

코드를 필요한 부분만 수정해서 올렸습니다
구조체 2강 1번 문제인 구조체를 이용해서 도서 대출 프로그램을 만드는 것인데 구조체를 이용해서 코드를 짜봤는데 책을 추가하는 함수에서

 [1번 문제점]

0번책 즉 *max_num이 0인 경우는 책의 입력이 잘되는데 그 뒤의 번호의 책이 문제입니다
*max_num으로 0보다 큰 수(1,2,3…99,100)을 입력받으면 책의 제목 저자 출판사가 입력한데로 출력되는 것이 아닌 알 수 없는 한자와 문자로 도배가 되네요 ㅜㅜ 어떻게 해결할 수 있을까요

 [2번 문제점]

*max_num이 예를 들어 3인 경우에는 0,1,2번째 책들이 기존에 입력받은 정보가 아닌 정보로 바뀝니다 데이터가 수정이 되버리네요

이틀간 고민해봤는데 도무지 해결책을 모르겠습니다 도와주시면 정말 감사하겠습니다

본인은 문제 없이 잘 작동 합니다. 전체 코드를 주실 수 있으신지요?

image

#include <stdio.h>
int add(int* max_num, struct reg_books* pbook);
int search(int* max_num, struct reg_books* pbook);
int compare(char* str1, char* str2);
int borrow(struct reg_books* pbook);
int return_b(struct reg_books* pbook);
int infor(int a, struct reg_books pbook);
struct reg_books {
char name[30];
char auth[30];
char publ[30];
int borrow;
int book_num;
};
int main() {
struct reg_books book[100];
int max_num;
int menu;

printf("                    도서 관리 프로그램 \n");

while (1) {
	printf("1. 책 추가하기 \n");
	printf("2. 책 검색하기 \n");
	printf("3. 책 빌리기 \n");
	printf("4. 책 반납하기 \n");
	printf("5. 프로그램 종료하기 \n");
	printf("원하는 기능의 번호를 누르세요 : ");
	scanf_s("%d", &menu);

	if (menu == 1) {
		add(&max_num, book);
	}
	else if (menu == 2) {
		search(&max_num, book);
	}
	else if (menu == 3) {
		borrow(book);
	}
	else if (menu == 4) {
		return_b(book);
	}
	else if (menu == 5) {
		return 0;
	}
	else {
		printf("올바른 명령이 아닙니다. \n");
	}
}
return 0;

}
int add(int* max_num, struct reg_books* pbook) {

printf("== 책을 추가합니다 \n");
printf("저장할 책의 번호를 눌러주세요 : ");
scanf_s("%d", max_num);		
printf("현재 저장할 책의 번호는 %d번 입니다. \n", *max_num);

printf("책의 제목을 입력해주세요 : ");
scanf_s("%s", &pbook->name[*max_num], 30);	
printf("책의 저자를 입력해주세요 : ");
scanf_s("%s", &pbook->auth[*max_num], 30);
printf("책의 출판사를 입력해주세요 : ");
scanf_s("%s", &pbook->publ[*max_num], 30);


printf("%d번 책제목 : %s, 저자 : %s, 출판사 : %s \n\n", *max_num, pbook[*max_num].name, pbook[*max_num].auth, pbook[*max_num].publ);	
pbook[*max_num].borrow = 0;



return 0;

}
int search(int* max_num, struct reg_books* pbook) {
char user_book[31];
int act;
printf("== 책을 검색합니다 \n");
printf(“1. 제목으로 검색하기 \n”);
printf(“2. 저자로 검색하기 \n”);
printf(“3. 출판사로 검색하기 \n”);
printf(“원하시는 검색 유형의 번호를 눌러주세요 : “);
scanf_s(”%d”, &act);

if (act == 1) {
	printf("책의 제목을 입력해주세요 : ");
	scanf_s("%s", user_book, 30);
	for (int a = 0; a <= *max_num; a++) {
		if (compare(pbook[a].name, user_book)) {
			/*String(4)Q3*/
			if (pbook[a].borrow == 1) {
				printf("그 책은 이미 대출됨 \n");
			}
			else {
				infor(&a, pbook);
			}
		}
		else if (a == *max_num && compare(pbook[a].name, user_book) == 0) {
			printf("찾으시는 책의 정보는 존재하지 않습니다. 책을 추가하세요 \n");
		}
	}
}
else if (act == 2) {
	printf("책의 저자를 입력해주세요 : ");
	scanf_s("%s", user_book, 30);
	for (int a = 0; a <= *max_num; a++) {
		if (compare(pbook[a].auth, user_book)) {
			infor(&a, pbook);
		}
		else if (a == *max_num && compare(pbook[a].auth, user_book) == 0) {
			printf("찾으시는 책의 정보는 존재하지 않습니다. 책을 추가하세요 \n");
		}
	}
}
else if (act == 3) {
	printf("책의 출판사를 입력해주세요 : ");
	scanf_s("%s", user_book, 30);
	for (int a = 0; a <= *max_num; a++) {
		if (compare(pbook[a].publ, user_book)) {
			infor(&a, pbook);
		}
		else if (a == *max_num && compare(pbook[a].publ, user_book) == 0) {
			printf("찾으시는 책의 정보는 존재하지 않습니다. 책을 추가하세요 \n");
		}
	}
}
else { printf("옳바른 명령이 아닙니다. \n"); }

return 0;

}
int compare(char* str1, char* str2) {

while (*str1) {
	if (*str1 == *str2) {
		str2++;
	}
	/*
	if (*str1 != *str2) {
		return 0;
	}
	str1++;
	str2++;
	*/
	str1++;
}
if (*str2 == '\0') return 1;

return 0;

}
int borrow(struct reg_books* pbook) {
int a;
printf("== 책을 대여합니다 \n");
printf(“책의 대여 유무 \n”);
printf(“책 대여 가능 = ‘0’, 책 대여 불가능 ‘1’ \n”);
printf(“책의 번호를 누르고 정보를 확인 한 후 대여를 해주세요 \n”);
scanf_s("%d", &a);
printf(“책의 번호 : %d, 책 제목 : %s, 책의 저자 : %s, 책의 출판사 : %s, 대여 상태 : %d \n”, a, pbook[a].name, pbook[a].auth, pbook[a].publ, pbook[a].borrow);
printf(“책을 대여 하시겠습니까? \n”);
printf(“대여하려면 ‘1’, 그렇지 않으면 '0’을 눌러주세요 : \n”);
scanf_s("%d", &(pbook[a].borrow));
printf(“책의 번호 : %d, 책 제목 : %s, 책의 저자 : %s, 책의 출판사 : %s, 대여 상태 : %d \n”, a, pbook[a].name, pbook[a].auth, pbook[a].publ, pbook[a].borrow);
return 0;
}
int return_b(struct reg_books* pbook) {
int a;
printf("== 책을 반납합니다 \n");
printf(“책의 대여 유무 \n”);
printf(“책 반납완료 = ‘0’, 책 대여 중 ‘1’ \n”);
printf(“책의 번호를 누르고 정보를 확인 한 후 반납를 해주세요 \n”);
scanf_s("%d", &a);
printf(“책의 번호 : %d, 책 제목 : %s, 책의 저자 : %s, 책의 출판사 : %s, 대여 상태 : %d \n”, a, pbook[a].name, pbook[a].auth, pbook[a].publ, pbook[a].borrow);
printf(“책을 반납 하시겠습니까? \n”);
printf(“반납하려면 ‘0’, 그렇지 않으면 '1’을 눌러주세요 : \n”);
scanf_s("%d", &(pbook[a].borrow));
printf(“책의 번호 : %d, 책 제목 : %s, 책의 저자 : %s, 책의 출판사 : %s, 대여 상태 : %d \n”, a, pbook[a].name, pbook[a].auth, pbook[a].publ, pbook[a].borrow);

return 0;

}
int infor(int a, struct reg_books pbook) {
printf(“책의 번호 : %d, 책 제목 : %s, 책의 저자 : %s, 책의 출판사 : %s, 대여 상태 : %d \n”, *a, pbook[*a].name, pbook[*a].auth, pbook[*a].publ, pbook[*a].borrow);
return 0;
}

여기있습니다!

답에 앞서 코드를 올릴 때 코드블록을 사용해주세요. (코드 선택 후 Ctrl Shift C)

if (compare(pbook[a].publ, user_book)) {
    infor(&a, pbook);
}

이 코드에서 pbook 부분에 오류날텐데 혹시 pbook 의 모든 인덱스를 넣어주려는 의도인가요?

어떤 상황인지는 알 것 같네요. 우선 코드 볼게요.

좋아요 1

문제점은 여러가지 있네요.

  1. 구조체 초기화 안하셨네요. struct reg_books book[100] = { 0 };
    위와 같이 초기화를 통해 유니코드 도배는 사라집니다.

  2. 변수를 출력할 때 나온 내용은 빈칸이였습니다. 이를 바탕으로 입력에 문제가 있다고 생각했구요.
    scanf_s("%s", &pbook.name[*max_num], 30); 이 코드가 문제였어요.
    argument 로 배열을 전달 했잖아요? 그러니 pbook[*max_num].name 에 입력값을 넣어야 해요.

    제가 이 질문 에 pbook 관련해서 물어봤어요. 이것도 pbook 이 아닌 pbook[a] 로 해주시면 될 것 같네요.

아래 코드는 올려주신 코드를 축소한 버전입니다.

#include <stdio.h>

int add(int* max_num, struct reg_books* pbook);

struct reg_books {
	char name[30];
	char auth[30];
	char publ[30];
	int borrow;
	int book_num;
};

int main()
{
	int max_num;
	int menu;
	struct reg_books book[100] = { 0 };

	printf("                    Book manager \n");

	while (1)
	{
		printf("1. Add Book \n");
		printf("5. Exit \n");
		printf(">> ");

		scanf_s("%d", &menu);

		if (menu == 1) {
			add(&max_num, book);
		}

		else if (menu == 5) {
			return 0;
		}

		else {
			printf("Unknown command \n");
		}
	}

	return 0;
}

int add(int* max_num, struct reg_books* pbook)
{
	printf("\n\n == Add \n");

	printf("Id : ");
	scanf_s("%d", max_num);

	printf("Title : ");
	scanf_s("%s", pbook[*max_num].name, 30);

	printf("Writer : ");
	scanf_s("%s", pbook[*max_num].auth, 30);

	printf("Company : ");
	scanf_s("%s", pbook[*max_num].publ, 30);

	printf("ID %d Title: %s, Writer : %s, Company : %s \n\n", *max_num, &pbook[*max_num].name, &pbook[*max_num].auth, &pbook[*max_num].publ);

	return 0;
}
좋아요 1

항상 친절히 답변해주셔서 감사합니다 덕분에 공부할 때 많은 도움을 받고 있네요
답변 내용대로 하니 정말 오류가 발생하지 않습니다 이해도 할 수 있었고 다시 한 번 감사드립니다

한 가지 더 궁금한 점은 제가 오류의 코드를(댓글의 전체 코드) 남겼을 때 왜
scanf_s("%s", &pbook->name[*max_num], 30); 이렇게 이상한 코드로 입력을 받았는데

*max_num이 0일 때는 잘 이행이 되는 것 인가요? 코드가 이상했음에도 0번째는 오류없이 잘 되었는데 이 부분은 이해가 되질 않네요 답변하기 어렵다면 안해주셔도 됩니다 추가적으로 궁금해서 여쭤봅니다!
항상 감사드립니다


0 일 때 입력한 값


1 일 때 입력한 값

우리는 한가지 사실을 알 수 있어요. 입력값이 index 1 부터 붙여넣기 되었어요. 그럼 원래 값이 어떻게 변할까요?