극초보의 linked list 질문입니다.
책 정보(id, name)을 추가(add)하고 삭제(remove)하고 검색(search)하고 제거(remove)하는 초보적인 프로그램을 짜보고 있는데요....
처음으로 linked list를 사용해 보았는데...인터넷에서 소스 보고 많이 많이 참고를 해가면서 첨으로 짜본건데...이상하게...3개 이상 add하면 에러나구...list도 마지막꺼는 name이 제대로 안나오구...이상하네요
사흘동안 시간날때마다 코드를 뚫어져라 보고 있는데...무엇이 문제인지...
전혀 감이 안오네요. 사실 linked list 자체도 잘 모르는 상태라...
도움 부탁드립니다.
===============================================
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define TRUE ( 1 )
#define FALSE ( 0 )
#define NAME_SIZ ( 10 )
#define ADD ( 1 )
#define RENT ( 2 )
#define RETURN ( 3 )
#define DISCARD ( 4 )
#define LIST ( 5 )
#define QUIT ( 6 )
#define RENTED ( 100 )
#define RETURNED ( 200 )
#define DISCARDED ( 300 )
typedef unsigned int bool;
typedef struct record BOOK;
struct record
{
char name[ NAME_SIZ ];
int id,
status;
BOOK *prev;
BOOK *next;
};
BOOK *book_head = NULL;
BOOK *book_tail = NULL;
void display_menu();
int get_menu_number();
void add_a_book();
void get_book_name( char book_name[ NAME_SIZ ] );
void get_book_id( int *book_id );
void list_all_books();
void print_a_book( BOOK *temp );
int main()
{
int menu = 0;
do
{
menu = get_menu_number();
switch( menu )
{
case ADD: add_a_book();
break;
case RENT: // borrow_a_book();
break;
case RETURN: // return_a_book();
break;
case DISCARD: //discard_a_book();
break;
case LIST: list_all_books();
break;
default: break;
}
}
while
( menu != QUIT );
return( 0 );
}
void display_menu()
{
printf( "\n" );
printf( "--------------------\n" );
printf( " a : Add a book \n" );
printf( " e : rEnt a book \n" );
printf( " r : Return a book \n" );
printf( " d : Discard a book \n" );
printf( " l : List books \n" );
printf( "--------------------\n" );
}
int get_menu_number()
{
char str[ BUFSIZ + 1 ],
dummy = ' ',
menu = ' ';
int menu_num = 0;
bool input_success = FALSE;
memset( str, 0x0000, sizeof( str ) );
do
{
display_menu();
printf( "Select? (q:quit) " );
gets( str );
if ( sscanf( str, "%c%c", &menu, &dummy ) == 1 )
if ( menu == 'a' || menu == 'r' || menu == 'e' ||
menu == 'd' || menu == 'l' || menu == 'q'
)
input_success = TRUE;
else
printf( "\nWrong menu.\n" );
else
printf( "\nWrong input.\n" );
}
while
( !input_success );
if ( menu == 'a' )
menu_num = ADD;
if ( menu == 'e' )
menu_num = RENT;
if ( menu == 'r' )
menu_num = RETURN;
if ( menu == 'd' )
menu_num = DISCARD;
if ( menu == 'l' )
menu_num = LIST;
if ( menu == 'q' )
menu_num = QUIT;
return( menu_num );
}
void add_a_book()
{
char book_name[ NAME_SIZ ];
int book_id = 0;
BOOK *book;
if( ( book = (BOOK *)malloc( sizeof( book ) ) ) == NULL )
{
fprintf( stderr,
"\nMemory allocation error!\n" );
}
else
printf( "\n%x\n", book );
memset( book_name, 0x0000, sizeof( book_name ) );
memset( book, 0x0000, sizeof( book ) );
get_book_name( book_name );
get_book_id( &book_id );
if ( book_head == NULL )
{
printf( "This is the first book.\n" );
book_head = book;
book_tail = book;
book->prev = NULL;
book->next = NULL;
}
else
{
book->prev = book_tail;
book_tail = book;
book->next = NULL;
}
strcpy( book->name, book_name );
book->id = book_id;
book->status = RETURNED;
}
void get_book_name( char book_name[ NAME_SIZ ] )
{
printf( "\nEnter book name : " );
gets( book_name );
}
void get_book_id( int *book_id )
{
char str[ BUFSIZ + 1 ],
dummy = ' ';
bool input_success = FALSE;
do
{
printf( "\nEnter book ID : " );
gets( str );
if ( sscanf( str, "%d%c", book_id, &dummy ) == 1 )
input_success = TRUE;
}
while
( !input_success );
}
void list_all_books()
{
BOOK *temp = book_head;
while( temp )
{
print_a_book( temp );
temp = temp->next;
}
}
void print_a_book( BOOK *temp )
{
printf( "\n" );
printf( "BOOK TITLE : %s\n", temp->name );
printf( "BOOK ID : %d\n", temp->id );
printf( "BOOK STATUS : %d\n", temp->status );
}
음..
add 함수만 봐서 다른데도 문제가 있는지는 잘 모르겠네요
BOOK *book
if( ( book = (BOOK *)malloc( sizeof( book ) ) ) == NULL ) ...
이부분...
sizeof(book) 은 포인터로서 4바이트가 됩니다.
Sometime, it is better for you to restart than recover.
Re: 극초보의 linked list 질문입니다.
book_head가 null아 아닐때(else 문에서) 이전 book_tail의 next포인터가 현재 추가하려는 book을 가리켜야 합니다.
감사합니다!
대단히 감사합니다! 역시...kldp에는 훌륭한 분들이 많은 것 같네요!!!
sizeof( *book)으로 malloc 시키니까 원하던 실행 결과가 나오네요..^^
정말 감사합니다..ㅜ.ㅡ
그런데 한 가지만 더 질문 드리고 싶은데...
book_head가 NULL 이 아닌 경우에
book_tail.next가 지금 만들어진 book을 가르켜야 한다고 하셨는데...
이미 그 바로 뒷 부분에서 book_tail = book 이 되므로...
book_tail.next = book 이 무용지물이 되지 않을까요?
(음음...우둔한 질문일지라도...이해해주시길.....죄송합니다...(__) )
Re: 감사합니다!
1. book1을 추가한다.
2. head가 없어서 book1이 head,tail
3. book2를 추가한다
4. head가 있어서 book2->prev에 book1를 넣는다
5. book_tail은 book2를 가르킨다
6. book2->next는 null
book1,book2의 상황
book1->prev는 null
book1->next는 null << error
book2->prev는 book1
book2->next는 null
댓글 달기