I want to have a stack that takes strings. I want to be able to push and pop strings off, as well as clear the whole stack. I think C++ has some methods for this. What about C?
A:
C hasn't got a standard library with the most common data structures like C++ does, you have to create the stack yourself.
Fortunately this is quite easy and doesn't need that many lines of code.
Georg
2009-12-17 07:12:21
Only a couple lines? Hell, there's at least 3 functions, even making those one liners doesn't satisfy your conditions.
GMan
2009-12-17 07:12:58
Isn't it possible to say "a couple of apples" for "a few apples" in English?
Georg
2009-12-17 07:29:45
Even a few, which is commonly regarded as 3-4, is too small. "Several" might be a better choice. :)
GMan
2009-12-17 07:36:28
"Several" are too many, a simple stack isn't that hard. Anyway, I'd be grateful for an answer to my previous question. :)
Georg
2009-12-17 07:43:32
LAst time I checked - C had a pretty good standard library. Yes, it doesn't have an implementation of stack data structure, but saying that C doesn't have a standard library is a bit too much...
Paulius Maruška
2009-12-17 08:30:02
@gs, "a couple" means two. Usually you wouldn't use it for any other quantity.
Mike Houston
2009-12-17 15:00:18
Indeed. You have a "few" functions that will be "several" lines each.
GMan
2009-12-18 03:05:42
Mike Houston: dictionary.com calls *a couple of* an idiom meaning "more than two, but not many, of; a small number of; a few: It will take a couple of days." The American Heritage 4th edition says "the inexactitude of *a couple of* may serve a useful purpose, suggesting that the writer is indifferent to the precise number of items involved" as in "*She lives only a couple of miles away*". Personally I think I use *a couple of* in this sense more often than the noun *couple* meaning two, but speakers differ.
Jason Orendorff
2009-12-18 12:54:31
+2
A:
Quick-and-dirty untested example. Uses a singly-linked list structure; elements are pushed onto and popped from the head of the list.
#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;
}
Edit
It would help to have an example of how to use it:
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);
...
}
You can declare stacks as auto variables, rather than using newStack() and destroyStack(), you just need to make sure they're initialzed properly, as in
int main(void)
{
struct stack_t myStack = {NULL, 0};
push (&myStack, "this is a test");
push (&myStack, "this is another test");
...
clear(&myStack);
}
I'm just in the habit of creating pseudo constructors/destructors for everything.
John Bode
2009-12-17 14:45:09