在C中创建一堆字符串

时间:2009-12-17 07:10:12

标签: c string stack

我想要一个带字符串的堆栈。我希望能够推出和弹出字符串,以及清除整个堆栈。我认为C ++有一些方法。那怎么样?

3 个答案:

答案 0 :(得分:8)

快速且肮脏的未经测试的示例。使用单链表结构;元素被推入并从列表的头部弹出。

#include <stdlib.h>
#include <string.h>

/**
 * Type for individual stack entry
 */
struct stack_entry {
  char *data;
  struct stack_entry *next;
}

/**
 * Type for stack instance
 */
struct stack_t
{
  struct stack_entry *head;
  size_t stackSize;  // not strictly necessary, but
                     // useful for logging
}

/**
 * Create a new stack instance
 */
struct stack_t *newStack(void)
{
  struct stack_t *stack = malloc(sizeof *stack);
  if (stack)
  {
    stack->head = NULL;
    stack->stackSize = 0;
  }
  return stack;
}

/**
 * Make a copy of the string to be stored (assumes  
 * strdup() or similar functionality is not
 * available
 */
char *copyString(char *str)
{
  char *tmp = malloc(strlen(str) + 1);
  if (tmp)
    strcpy(tmp, str);
  return tmp;
}

/**
 * Push a value onto the stack
 */
void push(struct stack_t *theStack, char *value)
{
  struct stack_entry *entry = malloc(sizeof *entry); 
  if (entry)
  {
    entry->data = copyString(value);
    entry->next = theStack->head;
    theStack->head = entry;
    theStack->stackSize++;
  }
  else
  {
    // handle error here
  }
}

/**
 * Get the value at the top of the stack
 */
char *top(struct stack_t *theStack)
{
  if (theStack && theStack->head)
    return theStack->head->data;
  else
    return NULL;
}

/**
 * Pop the top element from the stack; this deletes both 
 * the stack entry and the string it points to
 */
void pop(struct stack_t *theStack)
{
  if (theStack->head != NULL)
  {
    struct stack_entry *tmp = theStack->head;
    theStack->head = theStack->head->next;
    free(tmp->data);
    free(tmp);
    theStack->stackSize--;
  }
}

/**
 * Clear all elements from the stack
 */
void clear (struct stack_t *theStack)
{
  while (theStack->head != NULL)
    pop(theStack);
}

/**
 * Destroy a stack instance
 */
void destroyStack(struct stack_t **theStack)
{
  clear(*theStack);
  free(*theStack);
  *theStack = NULL;
}

修改

有一个如何使用它的例子会有所帮助:

int main(void)
{
  struct stack_t *theStack = newStack();
  char *data;

  push(theStack, "foo");
  push(theStack, "bar");
  ...
  data = top(theStack);
  pop(theStack);
  ...
  clear(theStack);
  destroyStack(&theStack);
  ...
}

您可以将堆栈声明为自动变量,而不是使用newStack()和destroyStack(),您只需要确保它们已正确初始化,如

int main(void)
{
  struct stack_t myStack = {NULL, 0};
  push (&myStack, "this is a test");
  push (&myStack, "this is another test");
  ...
  clear(&myStack);
}

我只是习惯于为一切创建伪构造函数/析构函数。

答案 1 :(得分:3)

尝试GNU Obstacks

来自维基百科:

  

在C编程语言中,Obstack是C标准库的内存管理GNU扩展。 “障碍”是动态管理的“对象”(数据项)的“堆栈”。

维基百科的代码示例:

char *x;
void *(*funcp)();

x = (char *) obstack_alloc(obptr, size); /* Use the macro. */
x = (char *) (obstack_alloc) (obptr, size); /* Call the function. */
funcp = obstack_alloc; /* Take the address of the function. */

IMO是什么让Obstacks变得特别:它不需要malloc()也不需要free(),但内存仍然可以动态分配。就像alloca()类固醇一样。它也可以在许多平台上使用,因为它是GNU C库的一部分。特别是在嵌入式系统上,使用Obstack而不是malloc()更有意义。

答案 2 :(得分:2)