링크리스트(연결리스트) add, delete, list 질문

다방커피의 이미지

항상 고수분들 답변 눈팅만 해오면서
알고리즘 몇개 공부해가는 학생이었는데
정말 고민끝에 염치없지만 긴 문제하나 질문드립니다ㅜㅜ

C언어를 이용한 링크드리스트 문제입니다
a를 누르면 add를실행
d를 누르면 delete를 실행
p를 누르면 print_list를 실행 같은 프로그램입니다.
먼저 add를 사용 입력받은 문자열과(name)과 숫자(number)을( 이때 문자열은 항상 3자 숫자는 항상 4자)
문자열크기에 맞춰 새로운 노드에 add, delete, list하는 문제입니다
new_node(), add(), delete(), print_list() 함수를 완성하는건데
아무리 짜봐도 프로그램이 제대로 작동하질 않습니다.

먼저 main.c와 backend.c 마지막 backend.h 헤더까지 입니다.

main.c는 압박이므로 자세히 보지않아도 될듯합니다

#include <stdio.h>
#include <stdlib.h>   // Necessary for exit()
#include "backend3.h"     
 
#define WELCOME_MESSAGE "Welcome to Address Book!\n"
#define COMMAND_PROMPT "ADDR>"
#define ADD_PROMPT "ADD NAME>>"
#define SEARCH_PROMPT "SEARCH NAME>>"
#define NUMBER_PROMPT "ENTER NUMBER>>>"
#define DELETE_PROMPT "DELETE NAME>>"
 
int prompt_command(char *, char *);
int prompt_name(char *, char *);
int prompt_number(char *, char *);
 
int main()
{
 
  char command[1];
  char name[3], number[4];
 
  init_pool();
 
  printf(WELCOME_MESSAGE);
 
  while (1) {
  restart:
    if (prompt_command(COMMAND_PROMPT, command) != 0 )
      goto restart;
    switch (command[0]) {
    case 'A':
    case 'a':
      if (prompt_name(ADD_PROMPT, name) !=0)
	goto restart;
      if (prompt_number(NUMBER_PROMPT, number) !=0)
	goto restart;
      add(name, number);
      break;
    case 'S':
    case 's':
      if (prompt_name(SEARCH_PROMPT, name) !=0)
	goto restart;
      search(name);
      break;
    case 'D':
    case 'd':
       if (prompt_name(DELETE_PROMPT, name) !=0)
	goto restart;
      delete(name);
      break;
    case 'Q':
    case 'q':
      printf("Quitting ... \n");
      return 0;
    case 'P':
    case 'p':
      print_list();
      break;
    default:
      printf("Please enter a valid command.\n");
      goto restart;
    }
  }
}
 
 
int prompt_command(char *s, char *p)
{
 
  char *q;
  char c;
 
  while (1) {
    printf("%s ", s);
    fflush(stdout);
    q=p;
    while (1) {
      c=getchar();
      if (c==EOF)
	exit(-1);      // Should let exit() take care of the sudden EOF.
      if (c=='\n')     
	break;
      if (q<p+1)
	*q=c;
      q++;
    }
    if (q==p+1)
      return 0;   // got a good command //
    if (q==p)
      return 1;   // just a <return>  //
    printf("Please type a command.\n");
  }
}
 
 
int prompt_name(char *s, char *p)
{
 
  char *q;
  char c;
 
  while (1) {
    printf("%s ", s);
    fflush(stdout);
    q=p;
    while (1) {
      c=getchar();
      if (c==EOF)
	exit(-1);      // Should let exit() take care of the sudden EOF.
      if (c=='\n')
	break;
      if (q<p+3)
	*q=c;
      q++;
    }
    if (q==p+3)
      return 0;   // got a good name //
    if (q==p)
      return 1;   // just a <return>  //
    printf("Please type a three-letter name.\n");
  }
}
 
 
int prompt_number(char *s, char *p)
{
  char *q;
  char c;
 
  while (1) {
    printf("%s ", s);
    fflush(stdout);
    q=p;
    while (1) {
      c=getchar();
      if (c==EOF)
	exit(-1);            // Should let exit() take care of the sudden EOF.
      if (c=='\n')
	break;
      if (q<p+4)
	*q=c;
      q++;
    }
    if (q==p+4)
      return 0;   // got a good number //
    if (q==p)
      return 1;   // just a <return>  //
    printf("Please type a four-digit number.\n");
  }
  return 0;
}

이어서 제일 중요한 backend.c 입니다.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "backend3.h"     
 
#define POOL_SIZE 5
 
// pool of memory
struct record pool[POOL_SIZE];
struct record * top=pool;  // pool is constant.  We need a pointer variable for stack top.
 
 
// comparison function for records
int compare(char key[3], struct record *);
 
// data
struct record * data = NULL; // Initially NULL.
 
 
void init_pool() // Initialize the pool
{
  int i;
  struct record *r=pool;
  struct record *s;
 
  pool[POOL_SIZE-1].next=NULL;  
 
  for(i=1;i<POOL_SIZE;i++) { 
    s=r++;
    s->next=r;
  }
}
 
 
// Get a node from the pool.  Exit if pool is empty.
struct record * new_node()  
{
	struct record* r;
	if (top == NULL) {
		printf("new_node() was not implemented.\n");
		printf("Pool is empty\n");
		exit(0);
	}
	else {
		r = top;
		top = r->next;
		return r;
}
 
// Push a node to the pool.
void free_node(struct record *r)
{
  r->next=top;
  top=r;
}
 
 
void add(char *name, char *number)
{
  printf("add() was not implemented.\n");
  // Error Message for duplicate name
  // printf("Can't add.  The name already exists!\n");
}
 
 
void search(char name[3])  
{
  struct record *r=data;
  int result;
 
  while(r!=NULL && (result=compare(name,r))>0)
    r=r->next;
  if(r==NULL || result<0)
    printf("Couldn't find the name.\n");
  else {
    print_name(r);
    printf(" : ");
    print_number(r);
    printf(" was found.\n");
  }
}
 
 
void delete(char name[3])
{
	struct record* r = top;
	if (compare(name, r) == 0) {
		struct record* s = r->next;
		r = s;
		r->next = s->next;
	}
	else
	{
		while (1) {
			struct record* s = r->next;
			if (compare(name, s) == 0) {
				r->next = s->next;
				break;
			}
			else
			{
				printf("no found\n");
				printf("delete() is not implemented.\n");
				break;
			}
		}
	}
 
}
 
 
/* Just a wrapper of strncmp(), except for the case r is NULL. 
 Negative value if key is less than r.
​0​ if key and r are equal.
 Positive value if key is greater than r. */
int compare(char key[3], struct record *r)
{
  if (r==NULL)  
    return -1;
  else
    return strncmp(key, r->name, 3);
}
 
// Prints ith name.
void print_name(struct record *r)
{
  print_data(r->name, 3);
}
 
// Prints ith number.
void print_number(struct record *r)
{
  print_data(r->number, 4);
}
 
void print_data(char * s, int n)
{
  int i;
  for (i=0; i<n; i++)
    putchar(s[i]);
}
 
void print_list()
{
  printf("print_list() was not implemented.\n");
}

마지막 헤더입니다.

void add(char [3], char [4]);
void search(char [3]);
void delete(char [3]);
 
// record structure
struct record {
  char name[3];
  char number[4];
  struct record * next;
};
 
void print_name(struct record *);
void print_number(struct record *);
void print_data(char *, int);
void print_list();
 
void init_pool();

일단 new_node(), delete 까지는 구현을 해놨습니다. 맞는지는 잘모르겠지만..
근데 null을 포함해서 받는strncpy 를 쓴것이 문제인가(3자리를 받는데 이러면 뒤에 null까지 4자리를받아서?)
그냥 제가 짠 add함수 자체의 문제인가는 모르겠지만
add를 해봐도 추가되었다고 나오지를 않습니다...
제가 짠 add가 있긴한데 너무 추잡합니다ㅠㅠㅠ

제발 도움좀주세요ㅜㅜㅜ

File attachments: 
첨부파일 크기
Package icon hw3 (1).zip187.69 KB
세벌의 이미지

일단은 실행은 된다는 거죠?
컴파일 할 때
gcc -Wall
해서 Warning 메시지까지 잘 살펴보셔요.

void add(char *name, char *number)
{
  printf("add() was not implemented.\n");
  // Error Message for duplicate name
  // printf("Can't add.  The name already exists!\n");
}

add 함수를 위와 같이 했다면 결과가 안 나오는 게 맞는데요?

https://wiki.kldp.org/wiki.php/DocbookSgml/Beginner_QA-KLDP#AEN70

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.