2009-12-17 5 views
4

문자열을 사용하는 스택을 갖고 싶습니다. 나는 전체 스택을 지우고 스트링을 튕겨 낼 수 있기를 원합니다. C++에는이 방법이 몇 가지 있다고 생각합니다. C는 어때?C에서 문자열 스택 만들기

+0

스택이 문자열을 복사하거나 전달 된 포인터를 사용해야합니까? 포인터를 저장하는 것만으로 훨씬 쉽지만 문자열이 변경되지 않는 문자열 리터럴 및/또는'char * '포인터로 작업하는 것을 알지 않는 한 거의 쓸모가 없으며 포인터는 유효하지 않게됩니다. 스택상의 '스토리지'. –

+0

원본 문자열을 덮어 쓸 수 있으므로 스택에서 문자열을 복사해야합니다. – neuromancer

+2

'strlen' +'malloc' +'strcpy'를 찾는다. 'strdup'을 가지고 있다면, ANSI C가 아닌 POSIX.1을 사용할 수 있습니다. 조금 더 쉬워졌습니다. 'pop'이나'clear'를 할 때 문자열을'free'하는 것을 기억하십시오. –

답변

2

Wikipedia's article about stacks을 참조하십시오.

+0

@gs : 링크를 아름답게 해줘서 고마워. 나는 그것을 작동시키지 못했습니다 ... –

+0

당신을 진심으로 환영합니다. :) –

3

시도 GNU Obstacks. 위키

: C 프로그래밍 언어에서

는 obstack의는 C 표준 라이브러리에 메모리 관리 GNU 확장이다. "obstack"은 동적으로 관리되는 "객체"(데이터 항목)의 "스택"입니다. 위키 백과에서

코드 예제 :

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 obstack은 특별하게 무엇을 : 그것은 malloc()free()을 필요로하지 않지만, 메모리는 여전히«을 동적으로»할당 할 수. 스테로이드의 경우는 alloca()입니다. 또한 GNU C 라이브러리의 일부이기 때문에 많은 플랫폼에서 사용할 수 있습니다. 특히 임베디드 시스템에서는 malloc() 대신 Obstacks를 사용하는 것이 좋습니다.

6

빠르고 테스트되지 않은 예제입니다. 단일 연결 목록 구조를 사용합니다. 요소는 목록의 머리 부분에 밀려 나오고 튀어 나옵니다.

#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); 
} 

저는 모든 것에 대해 의사 생성자/소멸자를 만드는 습관이 있습니다.