#include <ctype.h>
#include <error.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define CMD_S_INSERT "Insert"
#define CMS_S_EXTRACT "Extract"
#define CMD_S_PRINT "Print"
#define CMD_S_EXIT "Exit"
#define DEFAULT_VALUE 0

typedef int DATA_T;

typedef struct _NODE_T {
  DATA_T v;
  struct _NODE_T *p;
  struct _NODE_T *n;
} NODE_T;

typedef struct {
  int l_size;
  NODE_T *head;
  NODE_T *tail;
} LIST_T;

typedef struct {
  int q_cnt;
  NODE_T *head;
  NODE_T *tail;
} CQ_T;

enum {
  CMD_NONE = 0,
  CMD_INSERT,
  CMD_EXTRACT,
  CMD_PRINT,
  CMD_EXIT,
};

int isdigitstr(char *str)
{
  int len = 0, i;
  if (!str) {
    printf("arg is NULL\n");
    return 0;
  }
  len = strlen(str);
  for (i = 0; i < len; i++) {
    if (!isdigit(str[i])) {
      return 0;
    }
  }
  return 1;
}

int print_node(NODE_T *node)
{
  if (!node) {
    printf("arg is NULL\n");
    return -1;
  }
  printf("value=%d\n", node->v);
  return 0;
}

int update_node(NODE_T *node, DATA_T value)
{
  if (!node) {
    printf("arg is NULL\n");
    return -1;
  }
  node->v = value;
  return 0;
}

int alloc_node_mem(NODE_T **node, DATA_T value)
{
  if (!node) {
    printf("arg is NULL\n");
    return -1;
  }
  *node = (NODE_T *)malloc(sizeof(NODE_T));
  if (!*node) {
    printf("memory alloc failed\n");
    return -1;
  }
  memset(*node, 0, sizeof(NODE_T));
  (*node)->p = NULL;
  (*node)->n = NULL;
  (*node)->v = value;
  return 0;
}

int alloc_queue_mem(int l_size, LIST_T **queue)
{
  NODE_T *node;
  DATA_T default_value = DEFAULT_VALUE;
  int i, res = 0;
  if (l_size <= 0 || !queue) {
    printf("arg(%d/%p) is invalid\n", l_size, queue);
    return -1;
  }
  *queue = (LIST_T *)malloc(sizeof(LIST_T));
  if (!*queue) {
    printf("memory alloc failed\n");
    return -1;
  }
  (*queue)->head = NULL;
  (*queue)->tail = NULL;
  (*queue)->l_size = 0;
  for (i = 0; i < l_size; i++) {
    if (alloc_node_mem(&node, default_value) < 0) {
      printf("alloc_node_mem() failed\n");
      res = -1;
      break;
    }
    if ((*queue)->head == NULL) {
      (*queue)->head = (*queue)->tail = node;
    } else {
      ((*queue)->tail)->n = node;
      node->p = ((*queue)->tail);
      ((*queue)->tail) = node;
    }
    (*queue)->l_size++;
  }
  return l_size;
}

int destory_node(NODE_T *node)
{
  if (!node) {
    printf("arg is NULL\n");
    return -1;
  }
  node->p = NULL;
  node->n = NULL;
  free(node);
  return 0;
}

int destroy_queue(LIST_T *queue)
{
  NODE_T *node, *next = NULL;
  if (!queue) {
    printf("arg is NULL\n");
    return -1;
  }
  node = queue->head;
  if (node) {
    next = node->n;
  }
  while (node) {
    destory_node(node);
    node = next;
    if (node) {
      next = node->n;
    }
    queue->l_size--;
  }
  queue->head = queue->tail = NULL;
  free(queue);
  return 0;
}

int release_queue_mem(LIST_T *queue)
{
  if (!queue) {
    printf("arg is NULL\n");
    return -1;
  }
  return destroy_queue(queue);
}

int make_circle_queue(int *l_size, LIST_T **queue)
{
  char t_buf[64];
  if (!l_size) {
    printf("arg(l_size) is NULL\n");
    return -1;
  }
  if (!queue) {
    printf("arg(queue) is NULL\n");
    return -1;
  }
  *l_size = 0;
  while (*l_size <= 0) {
    printf("큐 사이즈를 입력해 주세요\n");
    scanf("%s", t_buf);
    *l_size = atoi(t_buf);
    if (*l_size <= 0) {
      printf("잘못 입력하셨습니다\n");
    }
  }
  alloc_queue_mem(*l_size, queue);
  return *l_size;
}

int init_cq(LIST_T *queue, CQ_T *cq) 
{
  if (!queue || !cq) {
    printf("arg(%p/%p) is invalid\n", queue, cq);
    return -1;
  }
  cq->head = queue->head;
  cq->tail = queue->head;
  cq->q_cnt = 0;
  return 0;
}

int print_queue(LIST_T *queue, CQ_T *cq)
{
  NODE_T *node;
  char t_buf[64];
  int i;
  if (!queue || !cq) {
    printf("arg(%p/%p) is invalid\n", queue, cq);
    return -1;
  }
  if (cq->q_cnt == 0) {
    printf("queue is empty\n");
    return 0;
  }
  node = cq->head;
  for (i = 0; i < cq->q_cnt; i++) {
    print_node(node);
    if (node == queue->tail) {
      node = queue->head;
    } else {
      node = node->n;
    }
  }
  return 0;
}

int insert_queue(LIST_T *queue, CQ_T *cq)
{
  NODE_T *next;
  char t_buf[64];
  if (!queue || !cq) {
    printf("queue arg(%p/%p) is invalid\n", queue, cq);
    return -1;
  }
  if (cq->q_cnt >= queue->l_size) {
    printf("queue is full\n");
    return 0;
  }
  do {
    printf("값을 입력하세요 :");
    scanf("%s", t_buf);
    if (!isdigitstr(t_buf)) {
      printf("잘못된 값입니다.\n");
    } else {
      break;
    }
  } while (1);
  update_node(cq->tail, atoi(t_buf));
  if (cq->tail == queue->tail) {
    next = queue->head;
  } else {
    next = cq->tail->n;
  }
  cq->tail = next;
  cq->q_cnt++;
  return 0;
}

int extract_queue(LIST_T *queue, CQ_T *cq)
{
  NODE_T *next;
  if (!queue || !cq) {
    printf("queue arg(%p/%p) is invalid\n", queue, cq);
    return -1;
  }
  if (cq->q_cnt <= 0) {
    printf("queue size is zero\n");
    return 0;
  }
  update_node(cq->head, DEFAULT_VALUE);
  if (cq->head == queue->tail) {
    next = queue->head;
  } else {
    next = cq->head->n;
  }
  cq->head = next;
  cq->q_cnt--;
  return 0;
}

int operate_queue(LIST_T *queue)
{
  int cmd = CMD_NONE;
  CQ_T cq;
  char t_buf[64];
  if (!queue) {
    printf("arg is NULL\n");
    return -1;
  }
  init_cq(queue, &cq);
  while (cmd != CMD_EXIT) {
    printf("명령을 입력해주세요 [%s/%s/%s/%s] : ", CMD_S_INSERT, CMS_S_EXTRACT,
           CMD_S_PRINT, CMD_S_EXIT);
    scanf("%s", t_buf);
    if (!strcasecmp(t_buf, CMD_S_INSERT)) {
      cmd = CMD_INSERT;
    } else if (!strcasecmp(t_buf, CMS_S_EXTRACT)) {
      cmd = CMD_EXTRACT;
    } else if (!strcasecmp(t_buf, CMD_S_PRINT)) {
      cmd = CMD_PRINT;
    } else if (!strcasecmp(t_buf, CMD_S_EXIT)) {
      cmd = CMD_EXIT;
      continue;
    } else {
      printf("명령이 잘못되었습니다\n");
    }
    switch (cmd) {
    case CMD_INSERT:
      insert_queue(queue, &cq);
      break;
    case CMD_EXTRACT:
      extract_queue(queue, &cq);
      break;
    case CMD_PRINT:
      print_queue(queue, &cq);
      break;
    default:
      break;
    }
  }
  return 0;
}

int main(int argc, char *argv[])
{
  int l_size;
  LIST_T *queue;
  make_circle_queue(&l_size, &queue);
  operate_queue(queue);
  release_queue_mem(queue);
  return 0;
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: